# SynapseTree — agent registration (auth.md)

SynapseTree is a cloud-hosted shared-memory service for AI tools and agents. An
agent can sign a user up and obtain an API key for that user's private memory
database. The human stays in charge: nothing is granted until the human approves
by email.

Machine-readable metadata:
- Authorization server: https://synapsetree.dev/.well-known/oauth-authorization-server
- Protected resource: https://api.synapsetree.dev/.well-known/oauth-protected-resource

## Endpoints

- Register: `POST https://api.synapsetree.dev/agent/identity`
- Poll for the key: `POST https://api.synapsetree.dev/oauth2/token`
- Revoke: `POST https://api.synapsetree.dev/oauth2/revoke`

## Flow

1. **Register.** Send `POST https://api.synapsetree.dev/agent/identity` with
   `Content-Type: application/json` and body `{"email": "<the human's email>"}`.
   An identity `assertion` from any provider may be included; it is logged and
   never acted on. The emailed link is always the identity proof.
2. The response is `{"claim_token": "stclaim_…", "user_code": "NNNNNN", "poll": {"token_endpoint": "…", "grant": "urn:synapsetree:claim", "interval": 5}}`.
   `poll.interval` is the number of seconds to wait between polls.
   **Show the `user_code` to the human.** At most 5 claim tokens may be
   outstanding per email.
3. **The human claims.** SynapseTree emails the human a claim link (usually
   within about a minute; the claim expires after 15 minutes). The consent page
   shows a 6-digit `user_code`; the human confirms it matches the one in your
   terminal, accepts the Terms of Service, and approves. The human email holder
   is the account principal and you act on their behalf.
4. **Poll.** Send `POST https://api.synapsetree.dev/oauth2/token` as
   `application/x-www-form-urlencoded` with `grant_type=urn:synapsetree:claim`
   and `assertion=<claim_token>`. Wait `poll.interval` seconds between polls. An
   `authorization_pending` or `slow_down` response may carry a new `interval`,
   which replaces it from then on.
   - `authorization_pending` (HTTP 400): not approved yet; keep polling.
   - `slow_down` (HTTP 400): poll less often.
   - `invalid_grant` (HTTP 400): expired, absent, or already redeemed; start over at step 1.
   - `key_limit_reached` (HTTP 400): the account already holds 10 live agent
     keys; the human must revoke one in the dashboard.
   - `database_name_taken` or `database_quota_exceeded` (HTTP 400): the
     human's account cannot take a new database right now (a name conflict or a
     plan limit); the human resolves it in the dashboard.
   - `server_error` (HTTP 500): transient; keep polling.
   On every error above except `invalid_grant`, the claim token stays valid
   until it expires — clear the problem and resume polling at step 4.
5. On approval the **first** poll returns exactly one key:
   `{"access_token": "stree_…", "token_type": "Bearer", "account_id": "…", "scope": "memory:full"}`.
   Polling again answers `invalid_grant` — store the key immediately.
6. **Use it.** Send `Authorization: Bearer stree_…` to `https://api.synapsetree.dev`.
   Registering again always mints a new key.

## Scope

- `memory:full` — the only scope issued to agents. Full access to the human's
  private memory database: read, write, query, graph, ingest, namespaces and
  maintenance. Ingest runs on the human's own inference key, registered in the
  dashboard; without one it answers 409 `inference_not_configured`.
- `memory:admin` — defined but not issued in v1. Memory export and the
  destructive endpoints (deleting facts, sources and namespaces) require it, so
  they are not agent-callable. The human performs those themselves.

Operations not available yet answer 501 `not_implemented`; today those are
`createExtractionPlan`, `getFactHistory`, `getSourceStatuses`,
`listSources`, `listDrafts`, `promoteDraft`, `getOntology`, `putOntology`
and `lintNamespace`, plus the `asOf` and `tokenBudget` query options and
`client_extraction` ingest.

## Using the API

- Contract (OpenAPI 3.1): https://synapsetree.dev/openapi.yaml
- Base URL: `https://api.synapsetree.dev`. Every `/v1` request sends `Authorization: Bearer stree_…`;
  registration (`POST /agent/identity`) and claim-token polling are the only
  unauthenticated calls (steps 1–4 above).
- Every `/v1` request body and response schema is in the contract, under the
  operation's `operationId`. For example, `POST /v1/memory/query` (`queryMemory`) takes a
  `QueryRequest` body — `{"namespaces": ["…"], "query": "…"}` at minimum —
  and answers `QueryResponse`.
- Errors are RFC 7807 `application/problem+json` with a stable `code`
  (the contract lists the few that are not: gateway responses and the token
  endpoint's RFC 6749 §5.2 error bodies).

## Keys

Keys (`stree_…`) do not expire. They stay valid until revoked. The human can
list, revoke, or regenerate keys at https://synapsetree.dev/dashboard; revocation takes
effect within 30 seconds (authorizer cache).

## Revocation

`POST https://api.synapsetree.dev/oauth2/revoke` (RFC 7009) with
`Authorization: Bearer stree_…` and form body `token=<key>`. It answers 200
identically whether or not the token was known.

## Rate limits

60 requests per minute per key (subject to change); exceeding it answers 429 with
`Retry-After`. Claim-token polling is paced by the `interval` hint.

## Events

Security event tokens (RFC 8935) are not supported
(`security_events_supported: false`).

## Links

- Pricing: https://synapsetree.dev/#pricing
- Terms of Service: https://equationalapplications.com/terms/
- Privacy: https://synapsetree.dev/privacy
- Contact: mailto:support@synapsetree.dev
