Skip to content

Submission API & auth

The ingestion API is not implemented in this repo yet — this is the contract the CLI and a future server will share.

Auth model: register once, submit non-interactively

You chose web signup issues a key. The flow:

  1. User signs up on the AgentSync web app (email or GitHub) — a one-time, browser-based step.
  2. The web app issues a submission key: as_live_<random>.
    • The full secret is shown once; the server stores only a hash.
    • The key has a public keyId (key_<id>) that appears in transcripts.
  3. The user installs the key on their machine — no interactive login at submit time thereafter:
    bash
    agentsync login as_live_xxx          # writes ~/.agentsync/credentials (0600)
    # or
    export AGENTSYNC_KEY=as_live_xxx     # env / CI secret
  4. Every submission authenticates with Authorization: Bearer as_live_xxx.

Keys are revocable and scoped from the web app (e.g. a CI-only key, or a key bound to the hiring-signal profile). Revocation is why a real key beats an anonymous self-issued one for the hiring use case.

Identity & the hiring-signal angle

A key is linked to the account that created it. By default submissions are pseudonymous (identityLinked: false); a profile or key can opt into identity linkage so a body of work attributes to a person. The submitter is always in control of which.

Endpoints

POST /v1/transcripts

Submit one normalized, already-redacted transcript.

Request

http
POST /v1/transcripts
Authorization: Bearer as_live_xxx
Content-Type: application/json
Idempotency-Key: <transcriptId>

Body: a Transcript validated against schema/transcript.schema.json.

Server-side processing

  1. Authenticate key → resolve keyId, account, allowed profiles.
  2. Rate-limit per key.
  3. Validate body against the JSON Schema (reject 400 with pointer on failure).
  4. Re-scan for high-confidence secrets (defense-in-depth). On a hit: 422 with the offending detector ids — the raw secret is never echoed back.
  5. Store the object; write an index row (transcriptId, keyId, pseudonym, source.agent, metrics, capturedAt).
  6. Idempotency-Key (= transcriptId) makes retries safe.

Responses

jsonc
// 201 Created
{ "transcriptId": "9f1c…", "status": "accepted", "url": "https://app.agentsync.dev/t/9f1c…" }

// 401 invalid/expired/revoked key
// 400 schema validation failed   → { "errors": [{ "path": "/events/3/type", "message": "…" }] }
// 422 server-side secret detected → { "rejected": "secret_detected", "detectors": ["aws"] }
// 429 rate limited                → Retry-After
// 413 payload too large

POST /v1/transcripts:initUpload (large payloads, future)

For transcripts above the inline limit, exchange metadata for a pre-signed URL, upload the body directly to object storage, then :complete. Specified now so the client can grow into it without an API break.

GET /v1/keys/self

Introspect the current key (account, scopes, allowed profiles, rate limits). Lets agentsync login confirm a key works before the first submit.

Versioning

  • Path-versioned (/v1). Additive changes stay in v1.
  • The body carries its own schemaVersion; the server accepts a documented range and rejects unknown majors with 400.

Transport & limits (defaults, tunable server-side)

  • HTTPS only; gzip request bodies.
  • Inline body cap ~5 MB → above that use the upload-init flow.
  • Per-key rate limit (e.g. 60 submissions / hour) with 429 + Retry-After.

Released under the MIT License.