Skip to content
PatchArc

Cloud API

The HTTP API behind patcharc share: authentication, upload sessions, capsules, shares, AI connections, and billing, with what is live in 0.2.0.

validated against patcharc 0.2.0 · 2026-08-22

Base URL https://api.patcharc.dev. Authenticate with Authorization: Bearer <token> where the token is the refresh token from ~/.patcharc/credentials.json. Errors are JSON: {"error": "<code>", "message": "<text>"}. CORS allows any origin.

$ TOKEN=$(jq -r .refresh_token ~/.patcharc/credentials.json)
$ curl -s https://api.patcharc.dev/healthz
{"ok":true,"version":"0.2.0"}

Authentication

MethodPathNotes
POST/v1/auth/deviceStart a device flow: {label, platform}{device_code, user_code, verification_url, expires_at, poll_interval}
POST/v1/auth/device/tokenPoll with {device_code}; authorization_pending, access_denied, expired_token until approved
POST/v1/auth/refresh{refresh_token} → rotated pair; the old token is revoked
DELETE/v1/auth/devices/:idRevoke a device and its tokens
GET/v1/meThe current user
GET/v1/accountsAccounts the user belongs to

Capsules

MethodPathNotes
POST/v1/upload-sessions{arc_id, size, sha256}; max 200 MB → {upload_id, upload_url, expires_at}
PUT/v1/upload-sessions/:id/putRaw capsule body; rejected unless its SHA-256 matches the declared hash
POST/v1/upload-sessions/:id/complete{sha256, size}; starts verification → {capsule_id, status: "verifying"}
GET/v1/capsules/:id/status{status, progress[], share_slug?}; statuses uploaded, verifying, published, failed_terminal
GET/v1/capsules/:id/reviewThe published review record (409 until published)
POST/v1/capsules/:id/reprocessRe-run verification
DELETE/v1/capsules/:idDelete the capsule, derived data, and shares

Upload sessions expire after 30 minutes.

Shares

MethodPathNotes
POST/v1/capsules/:id/shares{visibility, expires_at?}{share_id, slug, share_url, expires_at}; public requires the capsule to be published
GET/v1/shares/:idShare record
PATCH/v1/shares/:id{visibility?, expires_at?}; expires_at: null clears expiry
DELETE/v1/shares/:idRevoke; the link answers 410
POST/v1/shares/:id/rotateNew slug; the old one stops resolving
GET/a/:slugThe public ArcLink page (on patcharc.dev, not the API host)

See Sharing and ArcLinks for visibility semantics.

AI and BYOK

MethodPathNotes
POST/v1/ai/connections{name, provider, mode: "cloud_relay", api_key, base_url?}; the key is envelope-encrypted and never returned
GET/v1/ai/connectionsMetadata only
POST/v1/ai/connections/:id/testBroker-side decrypt and provider reachability check
DELETE/v1/ai/connections/:idRevoke
GET/v1/ai/models, /v1/ai/routesAvailable managed models and logical routes
GET/v1/ai/wallet, /v1/ai/usageCredits and 30-day usage
POST/v1/ai/jobsReserve credits and enqueue a summary job (orchestrator is a stub in 0.2.0)

Billing

MethodPathNotes
GET/v1/billing/plansPublic; the four plans
GET/v1/billing/subscription{subscription, stripe_enabled: false}
POST/v1/billing/checkout, /v1/billing/portalReturn mock URLs while Stripe is disabled

Rate limits

30 requests per minute on /v1/auth/*, 300 per minute elsewhere, keyed by user, then account, then IP. A 429 response carries retry-after.

Not available

Repository integrations (GitHub App, GitLab), organisation and member management, and webhooks other than Stripe's are not implemented in 0.2.0.