Skip to main content
Access is provisioned per organization. An administrator in your organization generates an api_secret from the Synthpop UI (app.synthpop.ai), or your Synthpop contact issues one. Synthpop does not store the secret after it is shown, so save it somewhere safe; generating a new one immediately invalidates the previous one. See Contact & support for the full request path and Authentication for how to use it.
Exchange your api_secret for a bearer token at POST /auth/get_token, then send that token as an Authorization: Bearer <token> header on every other call. The token is valid for 365 days (about a year) — cache it and re-exchange when it expires rather than fetching one per request. The API is default-deny: every endpoint except the token exchange and the docs requires the token. Full details in Authentication.
It is a single string with three colon-separated parts: provider:uid:secret. Older material may describe an api-key: prefix — that is just the provider segment (api-key:<uid>:<secret>). Always send the entire string, colons included, exactly as issued. Don’t trim, split, or add a prefix yourself.
Yes. Staging and production are separate systems with separate hosts and separate secrets:A secret issued for one environment will not work against the other. Build and test against staging, then swap the base URL and secret for production. Never send a production secret to the staging host or vice versa.
The API is asynchronous. POST /task/create returns immediately with status: "pending" and no results — the work is queued. You get the outcome one of two ways:
  • Poll GET /task/get until the Task reaches a terminal status (completed, failed, or invalid). Works for every organization.
  • Callback — supply a callback_template on create and Synthpop issues a GET to your URL when the Task finishes. This is opt-in and org-gated (org_settings.external_callback_enabled); the callback is a nudge to fetch, so your handler still calls GET /task/get for the result.
See Working with async results.
waiting is not a failure and not terminal — it means Synthpop needs more input (for example, a required document missing from the original upload) before it can continue. Add the missing files with POST /task/{uuid}/upload and the Task resumes on its own. A polling loop that only checks for terminal statuses will spin forever on a waiting Task, so handle it explicitly. See Responding to waiting tasks.(The public statuses are exactly pending, processing, waiting, completed, failed, and invalid.)
You submit the documents you already receive — referrals, orders, clinical notes, insurance cards, and forms — as PDFs, images, or text; audio is used for voice engagement. Attach one or more files under the uploads field of POST /task/create (a multipart/form-data request). Synthpop reads documents that are scanned, handwritten, or out of order. If a specific format is a concern for your integration, confirm with your Synthpop contact.
No. Deduplication is content-based: re-uploading identical bytes is a no-op. On an upload request where every file is a duplicate, the request instead returns 409 with {"detail": "All uploaded files are duplicates of existing data items."}. Note that this is separate from external_id, which is a correlation key you choose and later retrieve Tasks by — it does not make POST /task/create idempotent. Two creates with the same external_id and different content are two Tasks.
Under load, a deferrable Task is parked server-side (still reported as pending) and promoted to processing automatically when capacity frees up — no action needed. There is a per-organization cap on how many Tasks can be queued this way; when it is full, POST /task/create returns 429 Too Many Requests. Back off and retry the create later.
The 429 response is part of the contract but is not yet present in the committed OpenAPI snapshot behind the API reference. Handle it anyway; the reference will list it once the schema-regeneration job lands.
Not yet — official SDKs are on the roadmap. Today, use the OpenAPI spec to generate a client in your language, import it into Postman or Insomnia, or call the endpoints directly with cURL or Python requests. See SDKs & tools.
The version lives in the URL path — the v1 in /public/v1. There is one version today. Additive changes (new optional fields, new enum values, new endpoints) can happen within v1; a breaking change would arrive as a new path segment (/public/v2), served alongside v1. Do not rely on the decorative info.version string in openapi.json. See Versioning.
See Contact & support for how to reach the Synthpop team and what to include when reporting an API issue (environment, Task uuid or external_id, timestamps, request/response).