Request & Response
This page covers the conventions used across all Patholytix APIs — how to structure requests, what responses look like, and how custom action paths work.
Base URL
All API requests are made to:
https://api.dev2.patholytix.com/api/v1/
HTTP methods
| Method | Meaning | Returns |
|---|---|---|
GET | Read one or many resources | 200 OK |
POST | Create a resource | 201 Created |
PUT | Full update of an existing resource | 200 OK |
DELETE | Remove a resource | 204 No Content |
POST (action path) | Trigger an action on a resource | 200 OK or 202 Accepted |
Request format
Write operations (POST, PUT) send a JSON body with the Content-Type: application/json header:
curl -X POST "https://api.dev2.patholytix.com/api/v1/studies" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "studyName": "Phase II Study", "siteId": "..." }'
Read operations (GET, DELETE) have no request body.
Response format
All responses use application/json. Successful responses return the resource or a pagination envelope directly.
Error responses use application/problem+json and follow RFC 9457 Problem Details. See the Error Codes guide for the full status code table.
Path parameters
Path parameters identify a specific resource. They appear as {paramName} in the path:
GET /api/v1/studies/{studyId}/subjects/{subjectId}
All system-assigned identifiers are 24-character opaque strings. Treat them as case-sensitive.
Query parameters
Query parameters filter, paginate, and sort list responses:
GET /api/v1/studies/{studyId}/slides?subjectId=...&pageNumber=1&pageSize=25
See the Pagination guide for pageNumber, pageSize, sort, and sortDirection conventions.
Custom action paths
Some operations use a custom verb suffix on the path rather than a new HTTP method. These follow the pattern /{resource}:{action}:
| Path | Description |
|---|---|
POST /api/v1/studies/{studyId}/slides:bulkUpdate | Update up to 100 slides in one request |
POST /api/v1/image/jobs:ingest | Start an image ingest job |
POST /api/v1/image/jobs:transfer | Start an image transfer job |
POST /api/v1/image/jobs/{jobId}:retry | Retry a failed job |
POST /api/v1/image/jobs/{jobId}:cancel | Cancel a running job |
POST /api/v1/cloud/credentials/{credentialId}:validate | Test a stored credential |
GET /api/v1/image/jobs/{jobId}:streamProgress | Stream live progress over Server-Sent Events |
GET /api/v1/image/jobs/{jobId}:listFiles | List per-file transfer records |
The colon separates the resource path from the action name. These always use POST (mutating actions) or GET (streaming or list actions).
Asynchronous operations
Some operations return 202 Accepted immediately and process the work in the background. The response body contains a job record with a jobId and an initial status of CREATED.
Poll GET /api/v1/image/jobs/{jobId} for completion, or open the Server-Sent Events stream at GET /api/v1/image/jobs/{jobId}:streamProgress for live progress.
Idempotency
Image job creation endpoints accept an optional Idempotency-Key header. Resubmitting the same key returns the original job without creating a duplicate — safe to use when retrying on network failure:
-H "Idempotency-Key: ingest-batch-2026-09-01-001"
Attribute full-replace semantics
All PUT operations that accept an attributes map use full-replace semantics — the entire map is replaced on every call. Keys not present in the request body are removed. Send an empty object ({}) or omit the field entirely to clear all attributes.
{ "attributes": {} }
Server-managed attribute keys (such as SUBJID, MISPEC, FILE NAME) are stripped from any client-supplied map and re-enforced from the stored structural state — they cannot be overridden via the API.