Skip to content

API Design ​

The Medipal API is a versioned REST API over HTTPS with JSON bodies. It is described by an OpenAPI document generated from the platform schema and served by every instance. This page explains the conventions that apply to all endpoints; the practical steps for obtaining credentials and calling the API are in API Access.

Resources and paths ​

  • Every entity is a resource with a stable path under a versioned prefix. Collections are listed, created, read, updated and deleted with the usual HTTP methods.
  • Identifiers are opaque strings; never derive meaning from them.
  • Related actions that are not plain CRUD (publish a questionnaire, link a patient to a clinical record, invoke a plugin action) are exposed as explicit sub-resources rather than hidden in update calls.
  • Deleting a resource is a soft delete: the record keeps a deletion timestamp and disappears from default listings.

The OpenAPI document ​

The document is the contract. It lists every operation, its request and response models, the scopes it requires and the error codes it can return. The typed TypeScript clients used by the web and mobile apps are generated from it, and integrators can generate clients for their own language with any standard OpenAPI tool. The document is served by the instance together with interactive documentation.

Collection endpoints ​

All collection endpoints share one query interface.

CapabilityHow it works
Paginationlimit and offset query parameters. The response carries total, has_next and has_previous, so clients do not compute page state.
Sortingsort_by with a field name and sort_dir (asc or desc). Without sort_by, a stable default order keeps pages consistent.
FilteringField name equals value for equality. Other operators are suffixed to the field name: __ne, __lt, __lte, __gt, __gte, __in, __not_in, __ilike. Filters combine with AND.
Type safetyEach field accepts only the operators valid for its type; a boolean cannot be pattern-matched, a timestamp can be ranged.
Soft deleteDeleted records are hidden by default. include_deleted returns both, only_deleted returns the trash view.
DiscoverableAn unsupported sort or filter field returns a validation error listing the accepted values, so a client can correct itself without reading the source.

The response envelope is the same everywhere: the items under a resource-named key, followed by the paging fields.

json
{
  "webhooks": [],
  "total": 57,
  "limit": 25,
  "offset": 0,
  "has_next": true,
  "has_previous": false
}

Errors ​

Every error uses one envelope:

json
{
  "error": {
    "code": "QUERY_VALIDATION_ERROR",
    "message": "Unsupported sort field: colour",
    "details": {
      "field": "colour",
      "allowed_values": ["created_at", "id", "name"]
    }
  }
}
StatusFamily
400Validation errors: malformed body, unsupported query field or operator, business rule violations.
401The request is not authenticated, or the token is expired or malformed.
403The caller is authenticated but lacks a required scope or permission, or must complete a pending step first.
404The resource does not exist or is not visible to the caller.
409Conflict with the current state, for example a slot that already has a submission.
502An upstream system (a FHIR server, an identity provider) could not be reached.
500Unexpected server error. No internal details are included.

Codes are stable strings meant for programmatic handling; messages are for logs and developers and may change between releases.

Validation ​

Requests are validated against the generated models before any business logic runs. Validation covers types, required fields, formats such as timestamps and identifiers, and enumerations. Business validation (a schedule that ends before it starts, a publish request on a questionnaire without a schedule) happens in the service layer and is reported through the same envelope.

Idempotency and retries ​

  • Reads and deletes are safe to retry.
  • Creates are not automatically idempotent; a retried create after a network timeout may produce a duplicate. Look the resource up before retrying, or use a natural key where the resource has one (vault entries and roles have unique keys).
  • Submissions are protected by the schedule slot: a second submission for the same slot is rejected with a conflict, so a retried submission cannot double-count.
  • Treat 5xx and connection errors as retryable with backoff; treat 4xx as final.

Public endpoints ​

A small number of endpoints accept anonymous requests by design: reading published consent documents and submitting an anonymous questionnaire through its public link. Everything else requires a principal. See Anonymous Questionnaires.

Compatibility ​

The API version prefix changes only for breaking changes. Within a version, fields are added but not removed or retyped, so clients should ignore unknown fields. The web app and the API are released together on the same minor version so that their contract always matches.