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:
- User signs up on the AgentSync web app (email or GitHub) — a one-time, browser-based step.
- 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.
- 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 - 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
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
- Authenticate key → resolve
keyId, account, allowed profiles. - Rate-limit per key.
- Validate body against the JSON Schema (reject
400with pointer on failure). - Re-scan for high-confidence secrets (defense-in-depth). On a hit:
422with the offending detector ids — the raw secret is never echoed back. - Store the object; write an index row (
transcriptId,keyId,pseudonym,source.agent,metrics,capturedAt). Idempotency-Key(=transcriptId) makes retries safe.
Responses
// 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 largePOST /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 inv1. - The body carries its own
schemaVersion; the server accepts a documented range and rejects unknown majors with400.
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.