Developer documentation
Current context.
With permission.
Connect an application to a user's Self Runtime vault. Read selected, confirmed claims, respond to changes and make access visible.
https://api.selfruntime.devYour first context read
- Coming soon and add a confirmed claim, such as
communication.style. - Create a connection in the application. Give it a purpose, exact scopes, an expiry and a retention declaration.
- Copy its grant token once and save it as
SELF_RUNTIME_TOKENin your application's secret configuration. - Read the approved context. Keep the receipt ID if you want to acknowledge what you received.
curl https://api.selfruntime.dev/v1/context \
-H "Authorization: Bearer $SELF_RUNTIME_TOKEN"This is an explicit grant-token integration. Creating a connection does not install an assistant extension or authorize access to a platform's private memory. A compatible application must make the requests.
Authentication
Connected applications send Authorization: Bearer sr_live_…. The token belongs to one grant and one vault. The service checks expiry, revocation, scopes and permissions on each request.
Tokens are shown once at creation or rotation. Store them server-side or in a client that can protect secrets. Never embed a user's token in a public website bundle, URL or repository. Rotating a token replaces the previous credential.
The owner API under /api uses the owner's signed-in session through Better Auth. Application grant tokens do not replace owner sessions and cannot administer a vault. Context responses use Cache-Control: no-store.
Claims and current state
A claim is a JSON value in an exact namespace. Confirming a new version supersedes the previous current claim in that namespace. History preserves the relationship, source and validity interval.
An application can also make an eligible update current when the owner has explicitly enabled automatic updates on its grant. These claims retain application provenance and version history. A confirmed confidence value records acceptance by the owner or this delegated permission; it is not independent verification of the fact.
{
"id": "claim_example",
"namespace": "communication.style",
"label": "Response style",
"value": { "responseLength": "detailed" },
"status": "current",
"validFrom": "2026-08-01T00:00:00.000Z",
"validTo": null,
"supersedes": "claim_previous",
"confidence": "confirmed",
"source": { "type": "user_asserted" },
"sensitivity": "personal"
}Dates are ISO timestamps. Claims can be current, proposed, superseded, retracted or expired. Context reads exclude proposals, unconfirmed claims, inactive versions and claims outside their validity interval.
Namespaced values are extensible. Use stable, specific names such as communication.style, work.current_role or project.active. Namespace choice matters: sensitive categories are recognized conservatively even when a submitted sensitivity says “personal”.
Grants and permissions
A grant is the user's authorization for one application to receive bounded context. It contains an application name, stated purpose, exact scopes, expiry and retention period.
| Field | Meaning |
|---|---|
| scopes | Exact namespaces. No wildcard or automatic prefix expansion. |
| expiresAt | A required access deadline. Future reads are denied after expiry. |
| retentionDays | The recipient's declared retention period, not a guarantee of downstream erasure. |
| subscribeToChanges | Whether the connection can receive the approved change feed. |
| allowProposals | Whether the application may submit scoped updates. They require review by default. |
| autoApplyUpdates | Optional automatic updates, off by default. Requires allowProposals. Only non-sensitive claims valid now can become current automatically. |
| allowSensitive | Separate, explicit permission for sensitive namespaces. |
| webhookUrl | Optional public HTTPS destination for signed invalidations. |
The owner can enable or disable autoApplyUpdates when creating or editing a connection. Enabling it requires allowProposals: true. Exact scopes, expiry, revocation and sensitivity checks still apply. Sensitive claims require review even when allowSensitive is enabled. File and text imports always require review.
The Free plan allows three active connections; Plus allows 100 under fair use. All plans include the same basic correction, revocation, export and deletion controls.
An application name is user supplied, not a platform verification. Declaring a purpose describes the permitted use; technical scopes control which fields are returned. The service cannot determine every use of a value after an app receives it.
Read current context
GET/v1/context
Returns only current, confirmed claims permitted by the active grant. missing identifies approved namespaces without a current shareable claim. Every successful context read records a receipt.
{
"schemaVersion": "1",
"grant": {
"id": "grant_example",
"purpose": "Summarize research selected by the user",
"scopes": ["communication.style", "reading.preference"],
"expiresAt": "2026-10-01T00:00:00.000Z",
"retentionDays": 7
},
"claims": [
{
"id": "claim_example",
"namespace": "communication.style",
"value": { "responseLength": "detailed" },
"status": "current",
"confidence": "confirmed",
"source": { "type": "user_asserted" },
"validFrom": "2026-08-01T00:00:00.000Z",
"validTo": null
}
],
"missing": ["reading.preference"],
"receiptId": "receipt_example",
"version": 4
}Example identifiers and versions above are illustrative. Preserve claim IDs, source and validity when storing approved context. Do not substitute guessed values for missing fields.
Changes and durable cursors
GET/v1/changes?cursor=0&limit=50
Poll for permitted invalidations. Persist the returned cursor only after processing that page. Continue while hasMore is true. An event indicates that a claim changed; it does not contain the old or new personal value.
curl "https://api.selfruntime.dev/v1/changes?cursor=0&limit=50" \
-H "Authorization: Bearer $SELF_RUNTIME_TOKEN"The cursor advances monotonically within a vault. Results are filtered to the grant's permissions. After an invalidation, discard stale cached context and make a new authorized context read before using a replacement value. Deduplicate by event ID.
A new grant starts at the current vault version; it does not expose older events. A connection must have change subscriptions enabled to use the feed. A revoked or expired token cannot continue reading changes or personal values.
Automatically accepted application updates use this same change feed and webhook delivery. After a successful write, a new context read sees the current value immediately. The open vault refreshes about every 20 seconds; the webhook worker checks for pending deliveries every 5 seconds. These polling intervals are not a delivery-time guarantee.
Verify a remembered claim
POST/v1/verify
Compare a remembered value with the currently authorized claim. The namespace must be in the grant.
curl https://api.selfruntime.dev/v1/verify \
-H "Authorization: Bearer $SELF_RUNTIME_TOKEN" \
-H "Content-Type: application/json" \
-d '{"namespace":"communication.style","value":{"responseLength":"concise"}}'| Status | Meaning |
|---|---|
| valid | The submitted value matches current authorized context. |
| changed | The current claim differs. Inspect the returned claim and update your context. |
| unknown | No current authorized claim is available. Unknown is not confirmation. |
Propose an update
POST/v1/proposals
Requires allowProposals and permission for the exact namespace. Without automatic-update permission, a valid submission stays proposed and unverified until the owner confirms it. With autoApplyUpdates, a non-sensitive claim whose validity interval includes now can become current immediately.
curl https://api.selfruntime.dev/v1/proposals \
-H "Authorization: Bearer $SELF_RUNTIME_TOKEN" \
-H "Content-Type: application/json" \
-d '{"namespace":"communication.style","value":"Detailed answers","label":"Communication style"}'Inspect claim.status in the response. The endpoint name does not determine whether the update became current.
| Returned status | Outcome |
|---|---|
| current | Accepted under explicit automatic-update permission. Replaces the current version, preserves history and triggers normal change delivery. |
| proposed | Requires owner review. This includes sensitive claims, future-dated claims and updates without automatic permission. It does not change the current value. |
| expired | The submitted validity interval already ended. Stored in history only; it does not replace current context. |
Accepted automatic updates have source type application_updated and confirmed confidence. Review proposals use application_proposed and unverified. The source reference identifies the application. The service assigns these fields; a caller cannot grant itself authority by submitting its own status, source or confidence. Out-of-scope, expired-grant and revoked-grant requests are denied.
Do not describe a proposed value as already current or shared. Wait for confirmation and read the current view. Automatic-update permission does not apply to document or text imports.
Record what your app did
POST/v1/acknowledgements
Submit a receipt ID or event ID that was previously delivered to this grant, together with a truthful status.
curl https://api.selfruntime.dev/v1/acknowledgements \
-H "Authorization: Bearer $SELF_RUNTIME_TOKEN" \
-H "Content-Type: application/json" \
-d '{"receiptId":"receipt_example","status":"refreshed"}'| Status | Recipient's report |
|---|---|
| received | The application received the context or change. |
| refreshed | The application refreshed its working context. |
| invalidated | The old value was invalidated. |
| cannot_apply | The application could not apply the update. |
| deleted | The application reports that it deleted affected retained context. |
A successful webhook delivery and an explicit acknowledgement are separate records. Report only the action your application actually completed.
Signed invalidation webhooks
Set a public HTTPS webhook URL when creating a grant with change subscriptions enabled. The signing secret is returned once. Keep it separate from the grant token. The webhook contains event identifiers and a namespace when relevant, without personal claim values.
{
"id": "event_example",
"type": "claim.superseded",
"grantId": "grant_example",
"namespace": "communication.style",
"claimId": "claim_example",
"occurredAt": "2026-09-05T12:00:00.000Z"
}Verify X-Self-Runtime-Signature before processing. Its format is t=<unix-seconds>,v1=<hex-digest>. The digest is HMAC-SHA256 of timestamp + "." + rawRequestBody with the webhook secret. Reject timestamps outside a five-minute window. Compare digests in constant time.
import { createHmac, timingSafeEqual } from "node:crypto";
export function validSignature(rawBody, header, secret) {
const fields = Object.fromEntries(
header.split(",").map((part) => part.trim().split("="))
);
if (!/^\d+$/.test(fields.t ?? "")) return false;
if (!/^[a-f0-9]{64}$/i.test(fields.v1 ?? "")) return false;
if (Math.abs(Date.now() / 1000 - Number(fields.t)) > 300) return false;
const expected = createHmac("sha256", secret)
.update(fields.t + "." + rawBody)
.digest();
return timingSafeEqual(expected, Buffer.from(fields.v1, "hex"));
}Return HTTP 2xx after accepting a valid delivery. Delivery is at least once with retries; deduplicate by X-Self-Runtime-Event-Id. A revocation notification requests invalidation, while future context access remains denied.
Use the MCP interface
The authenticated endpoint is https://api.selfruntime.dev/mcp. Configure a Streamable HTTP client that supports an explicit Authorization: Bearer grant-token header. Each client has its own server-configuration format; use the endpoint and grant token in its documented HTTP settings. OAuth sign-in and authorization discovery are not provided.
The transport is stateless and returns JSON responses. Clients negotiate with initialize, send notifications/initialized, and then use tools/list or tools/call. Supported protocol versions are 2025-11-25, 2025-06-18 and 2025-03-26. Send the negotiated version in the MCP-Protocol-Version header on subsequent requests.
Notifications receive HTTP 202. GET and DELETE return HTTP 405; there is no server-initiated event stream or persistent session. Requests with an Origin header must match the deployment's configured ALLOWED_ORIGINS. Native clients normally omit this browser-origin header.
| Tool | Arguments |
|---|---|
| get_context | {} |
| get_changes | { cursor?, limit? } |
| verify_claim | { namespace, value } |
| propose_claim | { namespace, value, label?, … } |
| acknowledge_change | { receiptId?, eventId?, status } |
curl https://api.selfruntime.dev/mcp \
-H "Authorization: Bearer $SELF_RUNTIME_TOKEN" \
-H "MCP-Protocol-Version: 2025-11-25" \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_context","arguments":{}}}'MCP uses the same grant checks as REST. Tool access is not vault administration, and an assistant cannot broaden its own scopes or enable automatic updates. propose_claim follows the same automatic-update rules as POST /v1/proposals; inspect the returned claim.status. A claim left proposed still requires the owner's confirmation.
Vault owner API
These routes require the owner's signed-in browser session. They power the application and are separate from the grant-authenticated integration API.
Claims and profile
GET /api/vaultVault summary, claims including history/proposals, grants and namespaces.POST /api/claimsCreate a current claim or a proposal. Body includes namespace and JSON value.PATCH /api/claims/:idCreate a replacement version from optional updated fields.POST /api/claims/:id/confirmConfirm a proposal and supersede the previous current claim.POST /api/claims/:id/retractRetract a claim; DELETE /api/claims/:id is also supported.GET /api/claims/:id/historyRead the claim's version history.GET /api/profile · PUT /api/profileRead the profile or update the account name with { name }.Manage connections
GET /api/grantsList grants without tokens or signing secrets.POST /api/grantsCreate a grant; the response includes its one-time token and optional webhook secret.PATCH /api/grants/:idUpdate scopes, expiry, retention, permissions or purpose.POST /api/grants/:id/revokeRevoke future access.POST /api/grants/:id/rotateRotate the grant token and return its replacement once.GET /api/activityEvents, context receipts and delivery attempts, newest first.{
"applicationName": "My research assistant",
"purpose": "Summarize research selected by the user",
"scopes": ["communication.style", "reading.preference"],
"expiresAt": "2026-10-01T00:00:00.000Z",
"retentionDays": 7,
"subscribeToChanges": true,
"allowProposals": false,
"autoApplyUpdates": false,
"allowSensitive": false
}To explicitly authorize eligible automatic application updates, the owner sets both allowProposals and autoApplyUpdates to true. This does not change the connection's scopes or its separate sensitive-access permission.
Account operations
GET /api/usage returns the plan, connection usage, limits and billing availability. GET /api/config is public and describes the deployment's available sign-in, email and billing options.
DELETE /api/vault resets personal claims, connections and activity. DELETE /api/account cancels associated paid billing and removes the account. Both require the body {"confirmation":"DELETE"}. Export first if you want a separate copy.
Import, review and export
Upload selected ChatGPT or Claude JSON exports, PDF, Markdown, plain text or Word (.docx) files through the owner's session. A ChatGPT ZIP export containing conversations.json is also supported; arbitrary archives are not. File extraction suggests facts; it does not confirm or share them. All imports require owner review, including when a connection has automatic-update permission.
curl https://api.selfruntime.dev/api/import/upload \
-b owner-session-cookie.txt \
-F "file=@context-notes.md" \
-F "consent=true"Upload files up to 10 MB. Imports are limited to 10 attempts per hour per account, including extraction attempts. Scanned PDFs without selectable text need OCR before import.
The multipart endpoint is POST /api/import/upload with file and consent: "true". Plain-text import accepts POST /api/import with text and consent: true when external AI extraction is needed. Natural-language extraction uses the configured Anthropic provider only with consent. Raw files are not stored; the resulting proposals preserve source and evidence references.
Structured imports create proposals for the owner to confirm. The raw input text is discarded after processing. Send POST /api/import with {"text":"…","format":"text"} or format: "json".
communication.style: Detailed answers
communication.style: Clear and concise
project.active: Build a reading listJSON accepts an object mapping namespaces to values or an array of {"namespace":"…","value":"…","label":"…"} entries. Do not confirm imported claims on the user's behalf.
GET /api/vault/export returns a JSON attachment with claims, grants without secrets, events and receipts. GET /api/vault/context-card returns {"text":"…"}: a readable current profile the user can copy into an assistant. Copying a card does not create a live synchronization connection.
Errors and integration rules
REST failures return JSON with error and message. Show a clear recovery action instead of silently treating failure as empty context.
| HTTP status | How to respond |
|---|---|
| 400 | Fix invalid JSON, input fields or dates before retrying. |
| 401 | The credential or owner session is missing, expired or revoked. Request renewed authorization. |
| 403 | The grant does not permit this field or operation. Do not retry with broader access silently. |
| 404 | The requested object is not available to this account or grant. |
| 409 | A state conflict needs the latest data before you can continue. |
| 429 | Back off and respect service limits. |
| 5xx | Retry transient failures with bounded backoff; preserve your cursor. |
- Keep scopes exact and use the minimum context your task needs.
- Honor expiry and the retention period you declared.
- Validate webhook signatures against the raw body and deduplicate events.
- Do not mark an update acknowledged until your application handled it.
- Keep unknown and unconfirmed claims distinct from current confirmed context.
- Do not log personal values or grant secrets in routine request logs.