Welcome to Pyto!
The Pyto API is the canonical way to integrate Pyto with your own systems. It is exposed as a REST API and follows standard REST and HTTP conventions, so it should feel familiar if you have worked with web APIs before.
The canonical production URL is:
All API paths are relative to this URL. The /v1 prefix is part of the API contract and should be included in every request.
All requests must be sent over HTTPS. Pyto does not support plain HTTP for API calls, because requests may contain sensitive data and must be protected in transit.
The API may evolve over time as long as the changes do not break existing integrations. For example, Pyto may add new optional fields to request schemas, or new fields to response schemas. Your integration should ignore fields it does not use, and should not assume that an object will only contain the fields currently documented.
The API as a whole, or some specific endpoints, may eventually become deprecated. When a breaking change is required, Pyto will create a new API version and customers will need to migrate to that version within a timeline communicated by Pyto. If this happens, Pyto will notify customers ahead of the deprecation or removal.
Before making a request, your integration must authenticate with a bearer token. Include your API key in the Authorization header:
API keys are tied to an organization, not to an individual user. They should be treated as secrets, used only from trusted server-side environments, and never exposed in client-side code, public repositories, or logs.
If authentication fails, Pyto returns 401 Unauthorized. This can happen when the API key is missing or invalid. API keys do not expire automatically, but they can be rotated upon request, which makes the previous key invalid.
Once the request is authenticated, Pyto reads JSON request bodies and responds with JSON whenever a response body is returned. Request bodies should be encoded as UTF-8. When sending a request with a body, make sure to identify it as JSON using the Content-Type header:
Pyto follows standard HTTP methods and status codes. For example, requests that create data use standard HTTP semantics for creation, and responses use status codes to communicate whether the request succeeded, failed validation or authentication, or encountered a server-side issue.
Pyto follows the standard HTTP status codes defined by the HTTP RFCs. The table below provides an overview of the main status code classes used by the API. If you need more context on HTTP status codes in general, Wikipedia provides a convenient reference at https://en.wikipedia.org/wiki/List_of_HTTP_status_codes.
When a request fails, your integration should distinguish between permanent and transient errors before retrying. Permanent errors are caused by the request itself, so retrying the same request will not make it succeed. This is usually the case for 4XX responses, such as authentication errors or validation errors.
Transient errors are temporary failures that may succeed later without changing the request. This is usually the case for 5XX responses. These requests can be retried with a short delay, ideally using a limited number of attempts and a backoff strategy. Avoid retrying indefinitely.
A specific 4XX case worth calling out is 422. When Pyto returns this status code, it means the request could be understood, but one or more values did not pass validation. The response body is designed to help a human understand what needs to be corrected.
Validation error messages are not a stable contract for automated systems. Their wording, structure, and level of detail may change over time, so your integration should not depend on specific validation messages or parse them to drive business logic. For this reason, individual validation errors are intentionally not documented as API guarantees.
For example, a validation error for a missing required field may look like this:
This example is only illustrative. Your client should treat the 422 status code as the stable signal that the submitted data failed validation and surface the returned message to a human when appropriate.
Because validation errors are permanent errors, an unchanged request that returns 422 should not be retried automatically. Retrying it generally does not harm, but it will keep failing until the submitted data is corrected.