Hibák, hívási korlátok, verziózás
A hibaválaszok alakja, mikor érdemes újrapróbálni, a RateLimit fejlécek, és hogyan vezetünk ki egy útvonalat.
The shape of an error
Every error is JSON. There are two shapes, and the difference is where the error comes from.
| Source | Shape | Example |
|---|---|---|
| From Posty, because of a business rule | The msg field carries the human sentence. | { "msg": "No file provided" } |
| From request validation | The framework shape: statusCode, message, error. | { "statusCode": 400, "message": [...] } |
The OpenAPI document's ApiError schema also describes all of this in a machine-readable way, per status code, including whether you should retry.
Status codes
| Code | What it means | Typical cause |
|---|---|---|
| 400 | The request is invalid. | Missing required field, wrong date format, unknown enum value. |
| 401 | No valid credential. | Missing, wrong, or rotated key; expired OAuth token. |
| 403 | Not enough permission. | Missing scope, or the key's owner was demoted. The response names both. |
| 404 | No such resource. | Wrong identifier, or an item that belongs to another workspace. |
| 402 | The plan does not allow it. | The quota is used up, or the feature is not included in the plan. |
| 429 | Too many requests. | The call quota is used up. See the Retry-After header. |
| 5xx | Something went wrong on our side. | Temporary. Worth retrying. |
When to retry
400, 401, 403, and 404 will not go away until you change something: retrying is just load. 429 and 5xx are temporary. For those, exponential backoff is the right behavior.
If a POST /posts call ends in a timeout, you cannot tell a lost response from a lost request. The obvious retry publishes a post twice to someone's real account. Protect the call with an idempotency key, or query the calendar first.
Rate limits
Every response carries these headers, with a separate quota per path, per key:
| Header | What it says |
|---|---|
RateLimit-Limit | How large the quota is in the given window. |
RateLimit-Remaining | How much of it is left. |
RateLimit-Reset | How many seconds until it resets. Seconds, not a timestamp. |
RateLimit-Policy | A description of the current policy. |
Retry-After | Only with 429: how long to wait. |
curl -i https://api.posty.hu/public/v1/integrations \
-H "Authorization: psty_a_kulcsod"
RateLimit-Limit: 60
RateLimit-Remaining: 58
RateLimit-Reset: 41
RateLimit-Policy: 60;w=60Don't wait for the 429. You can slow down ahead of time from the remaining value. A scheduled sync that watches remaining never hits the limit.
Versioning and deprecation
The version is in the path: every public call lives under /public/v1. A breaking change would appear as a new version (/public/v2), and v1 keeps its contract.
- Additions happen inside v1: a new optional field, a new path, a new enum value. That is why your code should ignore fields it does not know.
- On deprecation the response gets a
Deprecation: trueheader, plus aSunsetheader with the date after which it no longer works, and aLinkheader with the details. - The Sunset date can never be closer than 180 days from the first
Deprecationheader.
Nothing is currently being deprecated. The machine-readable description is always in the OpenAPI document. If your code is generated from it, it picks up additions on its own.
You'll find the full list of endpoints on the Endpoints page.