Core concepts

Connections & webhooks

Before you can send anything for an elder, you need an approved connection to them. A connection answers two separate questions: who is this for, and are you allowed. The address handles the first; a caregiver's consent handles the second.

The elder's address

Every elder in Elderella has a memorable three-word address, like happy.sun.meadow@care.elderella.com. The family hands it to you the way they'd hand over a phone number — at intake, on a form, over the counter. It's the routing key: it says which elder a connection or a file is for. It is not a permission. Knowing an address doesn't let you do anything until a caregiver has approved you.

The three-word shape is intentional. It's easy to say out loud and read back, and — unlike an email address or a phone number — it carries nothing about the person, so sharing it discloses nothing.

Requesting a connection

Send the address to POST /v1/connections. You always get back a pending connection with a con_… id, for any well-formed address.

curl https://api.elderella.com/v1/connections \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "elder": "happy.sun.meadow@care.elderella.com" }'

{ "id": "con_9fH2k...", "status": "pending" }

Requesting the same address again returns the same id — the request is idempotent on (your partner account, address). A malformed address (wrong shape) is a 400; that's the only thing that ever fails here, and it tells you nothing about whether any real elder exists.

Who approves

A primary caregiver — one of the people responsible for that elder inside Elderella — sees your request and approves or declines it in the app. You have no say in who that is and no visibility into the decision as it happens; you simply learn, later, whether the connection became usable.

The lifecycle

StatusMeans
pendingRequested, awaiting a caregiver's decision. Also what you see if the address doesn't resolve, or was declined (see below).
approvedA caregiver approved it. You can now send files for this elder.
expiredA pending request sat unapproved past its window and lapsed.
revokedThe connection was severed — by the caregiver, or by you. Files stop flowing.
There is deliberately no declined status. If a caregiver declines your request, it continues to read as pending to you. That's on purpose: a distinct "declined" would tell you the elder exists and someone said no. Reading as pending keeps a decline and a never-resolved address indistinguishable.

Expiry

A pending request doesn't wait forever. If it isn't approved within its window (30 days), it lapses to expired. To try again after that, request the connection afresh. There is no webhook for expiry — poll if you need to know, or simply re-request.

The status never leaks who exists

Everything about connection status and timing is built so the API can't be used to probe Elderella's population:

These are contract guarantees, pinned by tests, not incidental behaviour. Don't build logic that depends on telling these cases apart; you can't.

Webhooks

Polling GET /v1/connections/{id} always works and is the fallback of record. But you don't have to poll: register a webhook endpoint with us at onboarding and we'll POST you an event when a connection changes.

Only two events are ever sent:

EventFires when
connection.approvedA caregiver approved your pending connection.
connection.revokedAn approved connection was severed — by the caregiver or by your own DELETE.

There is no connection.declined and no connection.expired event — consistent with the lifecycle above. The body looks like this:

{
  "id": "evt_5rT8w...",
  "type": "connection.approved",
  "created": 1753716000,
  "data": {
    "connection_id": "con_9fH2k...",
    "status": "approved"
  }
}

The id is your idempotency key — the same event may be delivered more than once, so dedupe on it. Delivery is at-least-once with exponential-backoff retries for up to 24 hours; if your endpoint is down that whole time, fall back to polling. Every delivery is signed with an Elderella-Signature header — always verify it before trusting a payload. The verification recipe is in the webhook signature guide.

Severing a connection yourself

You can end a connection from your side with DELETE /v1/connections/{id}. It moves to revoked and is idempotent — revoking an already-terminal connection still reports revoked.

curl -X DELETE https://api.elderella.com/v1/connections/con_9fH2k... \
  -H "Authorization: Bearer $TOKEN"

{ "id": "con_9fH2k...", "status": "revoked" }

Sending once you're connected

With an approved connection, send files at POST /v1/files (see the quickstart). One thing to know up front: if you try to send to an address that's unresolvable, unconsented, or revoked, all three return the identical 403 no_active_connection — the single no-oracle send error. Your integration should treat that one error as "there is no live connection here," without inferring which of the three it is.

Verify webhook signatures API reference