Reference
Every endpoint, request and response in the Partner API, generated from our OpenAPI contract, so the page cannot drift from the contract. Start with the quickstart for the end-to-end flow, authentication for tokens and scopes, and connections for consent and webhooks. The raw contract is at /partner-api.yaml.
Base URL https://api.elderella.com. Every operation, parameter and schema below is generated from the OpenAPI contract at /partner-api.yaml.
Partner authentication (client-credentials grant)
/oauth/tokenExchange client credentials for a partner bearer token. OAuth2 client-credentials grant (RFC 6749 §4.4). Returns a short-lived, scoped partner bearer. Every credential failure — unknown client_id, bad secret, revoked credential, suspended partner — returns the identical invalid_client error (no client_id enumeration oracle, in body and, via a dummy-hash compare, timing). Rate limited per IP.
Request body (required)
Content type: application/x-www-form-urlencoded, application/json.
| Field | Type | Description |
|---|---|---|
grant_type required | client_credentials | |
client_id required | string | |
client_secret required | string | |
scope | string | Space-separated subset of the partner's allowed scopes. Omit to be granted all Ring 1 scopes. |
Responses
| Status | Meaning |
|---|---|
| 200 | A partner bearer token. |
| 400 | invalid_request (missing fields), unsupported_grant_type, invalid_client (any credential failure), or invalid_scope. |
| 429 | The caller exceeded this endpoint's rate limit. |
Request, poll, and sever a partner↔elder connection
/v1/connectionsRequest a connection to an elder. Create a pending connection keyed on (partner, address). Always returns 202 { id, status: "pending" } for any valid-shape address — resolved or not. A repeat request for the same address returns the same con_… id. A malformed address is a 400 (leaks nothing about existence).
Request body (required)
Content type: application/json.
| Field | Type | Description |
|---|---|---|
elder required | string | The elder's Elderella address, e.g. happy.sun.meadow@care.elderella.com. |
Responses
| Status | Meaning |
|---|---|
| 202 | The pending connection. |
| 400 | The request was malformed (bad/missing field, bad address shape). |
| 401 | Missing, malformed, invalid, or revoked partner bearer. |
| 403 | A valid token that lacks the scope this route requires. |
| 429 | The caller exceeded this endpoint's rate limit. |
/v1/connections/{id}Poll a connection's status. Returns the connection's external status. An unknown id and one owned by another partner return an identical 404 (no cross-partner oracle).
Parameters
| Name | In | Required | Description |
|---|---|---|---|
id | path | yes | Opaque connection id, con_…. |
Responses
| Status | Meaning |
|---|---|
| 200 | The connection. |
| 401 | Missing, malformed, invalid, or revoked partner bearer. |
| 403 | A valid token that lacks the scope this route requires. |
| 404 | The id does not name a resource this partner can see (identical whether unknown or owned by another partner). |
| 429 | The caller exceeded this endpoint's rate limit. |
/v1/connections/{id}Sever a connection (partner-initiated). Revoke the connection → revoked. Idempotent: revoking an already- terminal connection still reports revoked.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
id | path | yes | Opaque connection id, con_…. |
Responses
| Status | Meaning |
|---|---|
| 200 | The revoked connection. |
| 401 | Missing, malformed, invalid, or revoked partner bearer. |
| 403 | A valid token that lacks the scope this route requires. |
| 404 | The id does not name a resource this partner can see (identical whether unknown or owned by another partner). |
| 429 | The caller exceeded this endpoint's rate limit. |
Send a file for a consented elder and poll its coarse status
/v1/filesSend a file for a consented elder. Multipart upload of any material about an elder (document, photo, audio, or text). Validates type (415) and size (413, 25 MB) before storing, then accepts it for asynchronous extraction and returns 202 { id, status: "received" }. An Idempotency-Key retry with the same bytes returns the same receipt; the same key with different bytes is a 409. An unresolvable address, an unconsented elder, and a revoked connection ALL return the identical 403 no_active_connection.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
Idempotency-Key | header | no | Opaque client key; a 24h store dedupes retries. |
Request body (required)
Content type: multipart/form-data.
| Field | Type | Description |
|---|---|---|
file required | string (binary) | The file bytes (≤ 25 MB; see the accepted MIME set in §5). |
elder required | string | The elder's Elderella address. |
purpose | string | Free-form hint; accepted as any string, never validated. |
Responses
| Status | Meaning |
|---|---|
| 202 | The file receipt. |
| 400 | The request was malformed (bad/missing field, bad address shape). |
| 401 | Missing, malformed, invalid, or revoked partner bearer. |
| 403 | insufficient_scope (token lacks files:write) or no_active_connection (the single no-oracle send error). |
| 409 | The Idempotency-Key was reused with a different payload. |
| 413 | The file exceeds the 25 MB limit. |
| 415 | The file's MIME type is not in the v1 accepted set. |
| 429 | The caller exceeded this endpoint's rate limit. |
/v1/files/{id}Poll a file's coarse status. Returns the coarse status of the partner's own submission. An unknown or not-owned id returns an identical 404.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
id | path | yes | Opaque file id, file_…. |
Responses
| Status | Meaning |
|---|---|
| 200 | The file. |
| 401 | Missing, malformed, invalid, or revoked partner bearer. |
| 403 | A valid token that lacks the scope this route requires. |
| 404 | The id does not name a resource this partner can see (identical whether unknown or owned by another partner). |
| 429 | The caller exceeded this endpoint's rate limit. |
The request and response shapes referenced above.
TokenRequest| Field | Type | Description |
|---|---|---|
grant_type required | client_credentials | |
client_id required | string | |
client_secret required | string | |
scope | string | Space-separated subset of the partner's allowed scopes. Omit to be granted all Ring 1 scopes. |
TokenResponse| Field | Type | Description |
|---|---|---|
access_token required | string | |
token_type required | Bearer | |
expires_in required | integer | Token lifetime in seconds. |
scope required | string | Space-separated granted scopes. |
OAuthErrorRFC 6749 §5.2 error shape (distinct from the /v1 error envelope).
| Field | Type | Description |
|---|---|---|
error required | invalid_request · unsupported_grant_type · invalid_client · invalid_scope | |
error_description | string |
ConnectionCreateRequest| Field | Type | Description |
|---|---|---|
elder required | string | The elder's Elderella address, e.g. happy.sun.meadow@care.elderella.com. |
ConnectionResource| Field | Type | Description |
|---|---|---|
id required | string | Opaque connection id, con_…. |
status required | pending · approved · expired · revoked | External connection status. declined is never surfaced — a decline reads as pending. |
FileSendRequest| Field | Type | Description |
|---|---|---|
file required | string (binary) | The file bytes (≤ 25 MB; see the accepted MIME set in §5). |
elder required | string | The elder's Elderella address. |
purpose | string | Free-form hint; accepted as any string, never validated. |
FileResource| Field | Type | Description |
|---|---|---|
id required | string | Opaque file id, file_…. |
status required | received · processed · failed | Coarse status of this submission. |
ErrorThe standard /v1 error envelope (design §5).
| Field | Type | Description |
|---|---|---|
error required | object |
Where error is:
| Field | Type | Description |
|---|---|---|
type required | string | Coarse grouping, e.g. invalid_request_error, authentication_error, rate_limit_error. |
code required | string | Stable machine-readable code (versioned contract) — e.g. unauthorized, not_found, insufficient_scope, no_active_connection, unsupported_media_type, file_too_large, idempotency_key_reuse, rate_limited. |
message required | string | Human-readable text; may change without a version bump. |
param | string | The offending field, when applicable. |
WebhookEventThe signed JSON body POSTed to a partner's registered webhook endpoint (design §8, §11). Delivered with an Elderella-Signature: t=<unix_ts>,v1=<hmac> header — HMAC-SHA256 over "{t}.{raw_body}" with the partner's signing secret. Only two event types are ever emitted; there is deliberately no connection.declined and no connection.expired event.
| Field | Type | Description |
|---|---|---|
id required | string | Opaque event id, evt_… — the partner's idempotency key. |
type required | connection.approved · connection.revoked | |
created required | integer | Event creation time, unix seconds. |
data required | WebhookConnectionData |
WebhookConnectionData| Field | Type | Description |
|---|---|---|
connection_id required | string | Opaque connection id, con_…. |
status required | pending · approved · expired · revoked | External connection status at the time of the event. |
Outbound events POSTed to your registered endpoint. Only the events below are ever sent; see the WebhookEvent schema for the signature scheme, and poll GET /v1/connections/{id} as the fallback of record.
| Event | Meaning |
|---|---|
connection.approved | A primary caregiver approved the partner's connection to an elder. |
connection.revoked | An approved connection was severed — by the caregiver or by the partner's own DELETE /v1/connections/{id}. |