Skip to main content
A Task is the single resource you program against. Every capability — intake, coverage, engagement — is a Task differentiated by its task_type. Everything you do is: create a Task, add data to it, read it back, or list Tasks. A Task is returned as a TaskDetails object from every endpoint except the download-link one.

Creating a Task

POST /task/create is the entry point. It is a multipart/form-data request:
cURL
The response comes back immediately with status: "pending" and empty verdicts — Synthpop processes the work in the background.
The API is asynchronous. Results exist only after you poll GET /task/get to a terminal status, or receive a callback. See Async results.

task_type (required)

task_type
string
required
Determines what processing Synthpop performs. Task types are provisioned for your organization during onboarding — there is no discovery endpoint, so the values available to you come from your Synthpop contact. Passing an unprovisioned type returns 400 "Task type 'X' not in list of tasks for your organization: [...]."

Optional inputs on create

uploads
file[]
Zero or more documents (PDFs, images, text, audio). Uploads are deduplicated by content — re-submitting identical bytes is a no-op, not a duplicate. (An upload where every file is a duplicate returns 409 rather than a no-op.)
request_spec
object
Task-type-specific JSON configuration. What it accepts depends on the task_type; leave it empty unless your Synthpop contact specifies fields.
external_id
string
Your own identifier for this Task, echoed back on every read. It is a correlation key, not an idempotency key — sending the same external_id twice creates two Tasks. Use it to tie Synthpop’s work back to a record in your system and to find related Tasks via GET /task/list.
name
string
An optional friendly label. If you omit it, Synthpop derives a name from the extracted content (e.g. "Jordan Lee (1985-04-12): Order intake").
callback_template
string
A URL pattern (with {uuid} and {external_id} placeholders) that Synthpop calls when the Task finishes. Callbacks are opt-in and org-gated — they fire only for organizations that have them enabled. See Async results.

The TaskDetails shape

uuid
string (uuid)
required
Synthpop’s unique ID for the Task.
external_id
string | null
required
Your correlation key (see above), or null.
task_type
string
required
The type the Task was created with.
status
TaskStatus
required
The current state. See the status lifecycle below.
name
string
required
A user-friendly name, derived from extracted inputs if you did not supply one.
category
string | null
required
A suggested category determined from the medical records found (e.g. "outpatient-referral"). null until enough has been extracted.
cleared
string (date-time) | null
required
Marks that follow-up work external to Synthpop is done. You set cleared with a boolean via PATCH /task/{uuid}/update; it reads back as the timestamp it was set at (or null if never set).
created
string (date-time)
required
When the Task was created.
latest_status_change
string (date-time)
required
When the status last changed (entered processing, waiting, completed, or failed). Equal to created while the Task is pending.
data_items
DataItem[]
required
The Task’s inputs, outputs, and extracted records. See Data Items.
issues
TaskIssue[]
required
Issues detected with the Task or its medical records. See Results.
verdicts
Verdict[]
Per-code approval decisions (validation tasks). See Results.
verdict_summaries
VerdictSummary[]
Per-code human-readable conclusions (validation tasks). See Results.

The status lifecycle

status is a TaskStatus — one of exactly these six values you can observe and no others. (The underlying TaskStatus enum also defines deferred, but the API never returns it — a deferrable Task reports as pending until it runs.)
waiting is not an error or a stuck state. A Task in waiting needs something from you before it can continue — typically a document flagged in its issues. Supply it and the Task resumes. See Responding to waiting tasks.

Frozen tasks — a 409 condition, not a status

When a newer patient-matched Task supersedes an older one, the older Task is frozen. Frozen is not a status value — it is a condition you discover by trying to add to the Task. Uploading to a frozen Task returns 409 with a TaskFrozenError body:
message
string
required
Human-readable description of the error.
current_task_uuid
string (uuid)
required
The UUID of the current, non-frozen Task that your uploads should be directed to.
Redirect your upload to current_task_uuid. This is detailed in Responding to waiting tasks.

Working with an existing Task

Every Task is org-scoped: it is visible only to the organization that owns it. See Authentication.