This guide covers conventions common to Phrase’s public REST APIs. Exact field names, parameters, and versioning schemes vary by product — check each API’s reference docs for specifics.
One payload, one job
Success responses describe the resource. Error responses describe what went wrong. The two never merge into one shape.
- A stable, machine-readable error code identifies the error class. Use it for programmatic handling — don’t parse the error message text.
- The human-readable message is for logs and debugging, not a contract. Its wording can change without notice.
- Some APIs list sub-issues for validation errors covering multiple invalid fields. Treat this as optional, not something every error includes.
- Pagination metadata is a separate concern from the resource it wraps — don’t merge it into the resource shape.
For your client: branch on response shape (success vs. error) using the HTTP status code, not by probing for a field’s presence. Keep error handling and resource parsing separate.
API contracts are open to addition, but closed for modification
New error codes, optional fields, and endpoint versions get added over time — existing ones don’t change or disappear.
- Don’t switch on enums or error codes without a default branch. A new value is expected, not an error.
- Ignore unknown JSON fields instead of rejecting the payload. Use lenient parsing.
- Treat enums as open-ended, not closed, sets.
For your client: write code that tolerates growth — default branches, tolerant parsing, open-ended enum handling. This costs nothing if we never add anything, and it means our additive changes won’t break your integration.
Versions aren’t interchangeable
A new version in the path (e.g. ../v3/…) typically signals a breaking change.
- Don’t assume a newer version’s payload is a superset of, or drop-in replacement for, an older one. Check the version-specific docs.
- Pin your client to one version per resource — don’t write code meant to handle “whatever version comes back.”
- Older versions usually stay available after a new one ships, so you can migrate on your own schedule — but check deprecation notices before assuming indefinite support.
For your client: treat each version as its own fixed contract. Pin to it explicitly, and move to a new version deliberately, not automatically.
Request only what you need
Pagination lets you consume large collections in the slice you need, rather than depending on the entire result set. The exact mechanism varies by API — page number/size, offset/limit, or headers instead of a body field — so check each API’s docs before writing generic pagination logic.
- The item list holds only the requested page — a well-designed API won’t force you to pull the full collection for one page.
- Any “total pages” field is normally derived from item count and page size — don’t hardcode assumptions about how it’s computed.
- Sort/filter metadata, where present, is only meaningful if the endpoint documents it as supported.
For your client: don’t couple your integration to the full width of a resource if you only need a subset. Request the page size you need, and read only the fields your logic depends on.
Depend on the documented contract, not on incidental behavior
Depend on documented status codes, error codes, and field names — not on things that happen to be observable today, like exact error text, field ordering, undocumented fields, or response timing.
- Don’t assume a status code by convention. A “created” status is only returned when documented for that endpoint; many POST operations that return the created resource respond with a generic “success” status instead.
- Depend on status and error codes, not error message text, which can change without notice.
- Expect these general categories, with API-specific codes: invalid input, authentication failure, authorization failure, not found, rate limiting, server error.
- Undocumented fields may appear in responses for forward compatibility — depend only on documented fields.
- For the full, current list of resources, parameters, and schemas, use the published OpenAPI/Swagger docs — that’s the contract to code against, not any single observed response.
For your client: code against the documented contract, never against what you happen to observe today. If it isn’t in the docs, don’t rely on it.