Open API Specification (1.1)

Download OpenAPI specification:

The Core Platform Edge API is organized around REST and follows the JSON:API specification. It has predictable, resource-oriented URLs, accepts and returns application/vnd.api+json payloads, and uses standard HTTP verbs, response codes, and authentication. Raw document bytes may alternatively be sent as multipart/form-data — see POST /api/upload_document.

You can use the Edge API in a sandbox without affecting live data. The bearer token you authenticate with determines whether a request runs against the live environment or a sandbox; the two are fully isolated. See the Authentication section below.

The Edge API's synchronous endpoints each act on a single resource. Batch submission from an object-storage bucket is described under POST /api/requests/batch (not yet implemented).

Authentication

The Edge API authenticates every request with a bearer token sent in the Authorization header:

Authorization: Bearer cp_live_9c8b7a6d5e4f3g2h1i0j

Each token belongs to a single environment (see the table below). Treat a token like a password: never embed it in client-side code, browser requests, or a public repository. If a token leaks, revoke it and issue a new one.

Making an authenticated request

curl https://{organisation}.platform.dyad.ai/api/requests \
  -H "Authorization: Bearer $EDGE_API_TOKEN" \
  -H "Accept: application/vnd.api+json"

All request and response bodies use the JSON:API media type application/vnd.api+json.

Environments

Every base URL is organisation-scoped: replace {organisation} with your organisation identifier, issued during onboarding. A request is served only for the organisation in its host, and the bearer token must belong to that same organisation.

Environment Base URL Token prefix
Production https://{organisation}.platform.dyad.ai cp_live_
Sandbox https://{organisation}.sandbox.platform.dyad.ai cp_test_

Note — the sandbox does not yet enforce token verification: any non-empty bearer token is currently accepted. This is temporary. Do not build against it — production rejects invalid tokens.

Endpoints that do not require a token

The API description documents are public:

  • GET /api/open_api — the OpenAPI document
  • GET /api/swaggerui — Swagger UI
  • GET /api/redoc — ReDoc

Authentication errors

A missing, malformed, or rejected token returns 401 Unauthorized with a JSON:API error document:

{
  "errors": [
    {
      "status": "401",
      "title": "Unauthorized",
      "detail": "A valid bearer token is required"
    }
  ]
}
Situation Status
No Authorization header 401
Header is not in Bearer <token> form 401
Token is rejected by verification 401

request

Submit documents and retrieve extraction results.

Submit a request

Submit a document for processing. The file is sent as a base64 string in data.attributes.document, data.attributes.request.entities selects what to extract from it, and the optional data.attributes.request.format selects how results are serialised (json or fhir).

This is a stateless submit-and-respond operation: nothing is persisted, and the outcome is delivered through the event emitted to the orchestrator (see GET /api/requests/{id}). For raw file bytes instead of base64, use POST /api/upload_document.

curl -X POST https://{organisation}.platform.dyad.ai/api/requests \
  -H "Authorization: Bearer $EDGE_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": {
      "type": "request",
      "attributes": {
        "document": "JVBERi0xLjQKJUVPRg==",
        "request": { "entities": ["slots"] }
      }
    }
  }'

Example response — 201 Created

{
  "data": {
    "attributes": {
      "document": "JVBERi0xLjQKJUVPRg==",
      "request": {
        "entities": [
          "slots"
        ],
        "format": "json"
      }
    },
    "id": "1f0a2b3c-4d5e-6f70-8192-a3b4c5d6e7f8",
    "type": "request"
  }
}
Authorizations:
bearerAuth
query Parameters
include
string^()(,())*$

Relationship paths to include in the response

object
Example: fields[request]=id,document,request

Limits the response fields to only those listed for each type

Request Body schema: application/vnd.api+json
required

Request body for the /requests operation on request resource

required
object

Responses

Request samples

Content type
application/vnd.api+json
{
  • "data": {
    }
}

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    }
}

Submit a text request

Work in progress

Submit raw text for processing instead of a document. The text is sent in data.attributes.text; data.attributes.request is identical to POST /api/requestsentities, plus the optional format. Processing, the event emitted to the orchestrator, and result retrieval via GET /api/requests/{id} are the same as for a document submission.

Until this is available the endpoint responds 404 Not Found.

curl -X POST https://{organisation}.platform.dyad.ai/api/requests/text \
  -H "Authorization: Bearer $EDGE_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": {
      "type": "request",
      "attributes": {
        "text": "Patient: Jane Doe. Clinic date: 17 Feb 2023.",
        "request": { "entities": ["slots"], "format": "json" }
      }
    }
  }'

Example response — 201 Created

{
  "data": {
    "attributes": {
      "request": {
        "entities": [
          "slots"
        ],
        "format": "json"
      },
      "text": "Patient: Jane Doe. Clinic date: 17 Feb 2023."
    },
    "id": "1f0a2b3c-4d5e-6f70-8192-a3b4c5d6e7f8",
    "type": "request"
  }
}
Authorizations:
bearerAuth
query Parameters
include
string^()(,())*$

Relationship paths to include in the response

object
Example: fields[request]=id,document,request

Limits the response fields to only those listed for each type

Request Body schema: application/vnd.api+json
required

Request body for the /requests/text operation on request resource

required
object

Responses

Request samples

Content type
application/vnd.api+json
{
  • "data": {
    }
}

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    }
}

Retrieve a request

Work in progress The response body for this endpoint is not finalised: the schema shown here is a placeholder and will change.

Once available, GET /api/requests/{id} will return the current state of the request identified by id — either its processing status (for example processing, succeeded, failed) while work is still in progress, or the extracted results once they are ready. The exact result shape is still being defined and depends on the entities and format requested at submission time; with format: fhir the results are returned as an HL7 FHIR R4 Bundle. The id may come from POST /api/requests, POST /api/upload_document, POST /api/requests/text, or a document within a batch.

Until then this endpoint responds 404 Not Found for every id.

curl https://{organisation}.platform.dyad.ai/api/requests/3f2a9c7e-1b4d-4e8a-9c2f-7a1e5d6b3c40 \
  -H "Authorization: Bearer $EDGE_API_TOKEN" \
  -H "Accept: application/vnd.api+json"

Example response — still processing

{
  "data": {
    "attributes": {
      "status": "processing"
    },
    "id": "3f2a9c7e-1b4d-4e8a-9c2f-7a1e5d6b3c40",
    "type": "request"
  }
}

Example response — processed (2 slots shown)

{
  "data": {
    "attributes": {
      "results": {
        "slots": [
          {
            "bboxes": [
              {
                "height": 0.009692132269099207,
                "left_x": 0.5042355788624445,
                "page_index": 1,
                "top_y": 0.2913340935005701,
                "width": 0.06696248487293266
              },
              {
                "height": 0.009692132269099207,
                "left_x": 0.7301331181928197,
                "page_index": 1,
                "top_y": 0.2913340935005701,
                "width": 0.021379588543767647
              }
            ],
            "concept_id": null,
            "date": null,
            "entity_type": null,
            "explanation": "AI predicted slot value",
            "extra_info": null,
            "laterality": null,
            "problem_resolution_status": null,
            "restriction_name": null,
            "slot_id": "97b16e36-f647-4f19-bcec-7daac8a29b90",
            "snomed_code": null,
            "snomed_term": null,
            "table": "requests_tasks",
            "text": "Referrals No",
            "units": null,
            "value": null
          },
          {
            "bboxes": [
              {
                "height": 0.009407069555302166,
                "left_x": 0.2779346510689794,
                "page_index": 0,
                "top_y": 0.515678449258837,
                "width": 0.06655909640984267
              }
            ],
            "concept_id": "9663501000001101",
            "date": "2026-09-04",
            "entity_type": "medication",
            "explanation": "AI predicted slot value",
            "extra_info": null,
            "laterality": null,
            "problem_resolution_status": null,
            "restriction_name": null,
            "slot_id": "59a05416-e091-4f66-8ef8-dd12a18d2130",
            "snomed_code": "9663501000001101",
            "snomed_term": "Entonox",
            "table": "medication",
            "text": "Entonox",
            "units": null,
            "value": false
          }
        ]
      },
      "status": "succeeded"
    },
    "id": "3f2a9c7e-1b4d-4e8a-9c2f-7a1e5d6b3c40",
    "type": "request"
  }
}
Authorizations:
bearerAuth
path Parameters
id
required
string
query Parameters
include
string^()(,())*$

Relationship paths to include in the response

object
Example: fields[request]=id,document,request

Limits the response fields to only those listed for each type

Responses

Response samples

Content type
application/vnd.api+json
Example

Processing finished. attributes.results.slots holds the extracted slots.

{
  • "data": {
    }
}

Upload a document via multipart/form-data

Submit a document as raw file bytes via multipart/form-data, for callers who would rather not base64-encode. The file goes in the document part and the JSON-encoded request metadata in the request part. Processing and result retrieval via GET /api/requests/{id} are identical to POST /api/requests.

curl -X POST https://{organisation}.platform.dyad.ai/api/upload_document \
  -H "Authorization: Bearer $EDGE_API_TOKEN" \
  -F "document=@referral.pdf" \
  -F 'request={"entities":["slots"],"format":"json"}'

Example response — 201 Created

{
  "document": "JVBERi0xLjQKJUVPRg==",
  "id": "1f0a2b3c-4d5e-6f70-8192-a3b4c5d6e7f8",
  "request": {
    "entities": [
      "slots"
    ],
    "format": "json"
  }
}

Example error — 400 Bad Request

{
  "errors": [
    {
      "detail": "The `request` part must be valid JSON",
      "status": "400",
      "title": "Invalid request"
    }
  ]
}
Authorizations:
bearerAuth
Request Body schema: multipart/form-data
optional

Document upload

document
required
string <binary>

The file to upload

request
required
string

JSON-encoded request metadata, e.g. {"entities":["slots"],"format":"json"}

Responses

Response samples

Content type
application/json
{
  • "document": "JVBERi0xLjQKJUVPRg==",
  • "id": "1f0a2b3c-4d5e-6f70-8192-a3b4c5d6e7f8",
  • "request": {
    }
}

batch

Submit many documents at once from an object-storage bucket. Work in progress.

Submit a batch of documents

Work in progress

Submit many documents in one call by pointing Core Platform at a location in an object-storage bucket it has been granted read access to. data.attributes.request is applied to every document in the batch; data.attributes.source names the bucket and either a prefix to enumerate or an explicit list of keys.

The call returns 201 Created with a batch id. Poll GET /api/requests/batch/{id} for progress and the per-document request ids, then retrieve each document with GET /api/requests/{id} as normal.

Until this is available the endpoint responds 404 Not Found.

curl -X POST https://{organisation}.platform.dyad.ai/api/requests/batch \
  -H "Authorization: Bearer $EDGE_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": {
      "type": "request-batch",
      "attributes": {
        "request": { "entities": ["slots"], "format": "json" },
        "source": { "bucket": "acme-inbound", "prefix": "referrals/2023-02/" }
      }
    }
  }'

Example response — 201 Created

{
  "data": {
    "attributes": {
      "request": {
        "entities": [
          "slots"
        ],
        "format": "json"
      },
      "source": {
        "bucket": "acme-inbound",
        "prefix": "referrals/2023-02/"
      },
      "status": "pending"
    },
    "id": "b1a2c3d4-0000-4000-8000-000000000001",
    "type": "request-batch"
  }
}
Authorizations:
bearerAuth
query Parameters
include
string^()(,())*$

Relationship paths to include in the response

Request Body schema: application/vnd.api+json
required

Request body for the /requests/batch operation

required
object

Responses

Request samples

Content type
application/vnd.api+json
{
  • "data": {
    }
}

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    }
}

Retrieve a batch

Work in progress

Return the state of the batch identified by id: its overall status, totals, and a documents array pairing each source object key with its per-document request id and status. Individual documents are retrieved with GET /api/requests/{id}.

Until this is available the endpoint responds 404 Not Found for every id.

curl https://{organisation}.platform.dyad.ai/api/requests/batch/b1a2c3d4-0000-4000-8000-000000000001 \
  -H "Authorization: Bearer $EDGE_API_TOKEN" \
  -H "Accept: application/vnd.api+json"

Example response — 200 OK

{
  "data": {
    "attributes": {
      "documents": [
        {
          "id": "3f2a9c7e-1b4d-4e8a-9c2f-7a1e5d6b3c40",
          "key": "referrals/2023-02/0001.pdf",
          "status": "succeeded"
        },
        {
          "id": "5c6d7e8f-2a3b-4c5d-9e0f-1a2b3c4d5e6f",
          "key": "referrals/2023-02/0002.pdf",
          "status": "succeeded"
        },
        {
          "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
          "key": "referrals/2023-02/0003.pdf",
          "status": "pending"
        }
      ],
      "request": {
        "entities": [
          "slots"
        ],
        "format": "json"
      },
      "source": {
        "bucket": "acme-inbound",
        "prefix": "referrals/2023-02/"
      },
      "status": "processing",
      "totals": {
        "documents": 3,
        "failed": 0,
        "pending": 1,
        "succeeded": 2
      }
    },
    "id": "b1a2c3d4-0000-4000-8000-000000000001",
    "type": "request-batch"
  }
}
Authorizations:
bearerAuth
path Parameters
id
required
string
query Parameters
include
string^()(,())*$

Relationship paths to include in the response

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    }
}

notifications

Register webhook callbacks for request and batch completion. Work in progress.

Subscribe to batch notifications

Work in progress

Register an HTTPS url to be called for the batch identified by id. By default only batch.completed / batch.failed are delivered; add batch.document.succeeded / batch.document.failed to events to also be notified per document. Optionally supply a secret for callback signing. Returns 201 Created with a subscription id.

The shape of the callback Core Platform sends is documented under Callbacks below.

Until this is available the endpoint responds 404 Not Found for every id.

curl -X POST https://{organisation}.platform.dyad.ai/api/requests/batch/b1a2c3d4-0000-4000-8000-000000000001/notifications \
  -H "Authorization: Bearer $EDGE_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": {
      "type": "notification-subscription",
      "attributes": {
        "url": "https://acme.example.com/hooks/core-platform",
        "events": ["batch.completed", "batch.failed"]
      }
    }
  }'

Example response — 201 Created

{
  "data": {
    "attributes": {
      "events": [
        "request.succeeded",
        "request.failed"
      ],
      "url": "https://acme.example.com/hooks/core-platform"
    },
    "id": "ns_7b2c\u2026",
    "type": "notification-subscription"
  }
}
Authorizations:
bearerAuth
path Parameters
id
required
string
Request Body schema: application/vnd.api+json
required

Notification subscription to register

required
object

Responses

Callbacks

Request samples

Content type
application/vnd.api+json
{}

Response samples

Content type
application/vnd.api+json
{}

Callback payload samples

Callback
POST: Batch lifecycle event
Content type
application/json
{
  • "created_at": "2023-02-17T10:15:00Z",
  • "data": {
    },
  • "id": "evt_9c8b7a…",
  • "type": "batch.completed"
}

Subscribe to request notifications

Work in progress

Register an HTTPS url to be called when the request identified by id reaches a terminal state (succeeded or failed). Optionally narrow delivery with events and supply a secret for callback signing. Returns 201 Created with a subscription id.

The shape of the callback Core Platform sends is documented under Callbacks below.

Until this is available the endpoint responds 404 Not Found for every id.

curl -X POST https://{organisation}.platform.dyad.ai/api/requests/3f2a9c7e-1b4d-4e8a-9c2f-7a1e5d6b3c40/notifications \
  -H "Authorization: Bearer $EDGE_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": {
      "type": "notification-subscription",
      "attributes": {
        "url": "https://acme.example.com/hooks/core-platform",
        "events": ["request.succeeded", "request.failed"]
      }
    }
  }'

Example response — 201 Created

{
  "data": {
    "attributes": {
      "events": [
        "request.succeeded",
        "request.failed"
      ],
      "url": "https://acme.example.com/hooks/core-platform"
    },
    "id": "ns_7b2c\u2026",
    "type": "notification-subscription"
  }
}
Authorizations:
bearerAuth
path Parameters
id
required
string
Request Body schema: application/vnd.api+json
required

Notification subscription to register

required
object

Responses

Callbacks

Request samples

Content type
application/vnd.api+json
{}

Response samples

Content type
application/vnd.api+json
{}

Callback payload samples

Callback
POST: Request lifecycle event
Content type
application/json
{
  • "created_at": "2023-02-17T10:15:00Z",
  • "data": {
    },
  • "id": "evt_9c8b7a…",
  • "type": "request.succeeded"
}