Setup guide

From provisioned session to stored receipt

This is the actual sequence the control plane runs: a checkout session creates the workspace and its quota, the claim endpoint reveals a one-time API key, and that key writes receipts and reads usage. Everything below is the live API, not a mock-up.

  1. Create the workspace session. Post a plan and a billing email. Plans are starter and team.
    curl -X POST https://correctover.com/api/v1/checkout/session \
      -H "content-type: application/json" \
      -d '{"plan":"starter","email":"[email protected]"}'
    
    # 200
    # {"id":"cs_…","url":"https://checkout.stripe.com/…","mode":"stripe"}
    The response carries a redirect URL for card payment. On completion the provider calls our webhook, which activates the workspace and sets the receipt quota for the plan.
  2. Claim the API key once. The success redirect lands on the console with ?session_id=…. The console exchanges that id for the key.
    curl "https://correctover.com/api/v1/account/claim?session_id=cs_…"
    
    # 200
    # {"email":"[email protected]","plan":"starter","quota":50000,"used":0,
    #  "api_key":"cov_…",
    #  "message":"Copy this key now. It will not be shown again."}
    This is deliberately single-use. After the first successful reveal the key is deleted from storage, and a second call returns "api_key": null with the message that the key was already revealed or has expired. If it is lost, the key is rotated from support — it is not re-readable.
  3. Write a receipt. Send the decision your runtime already made.
    curl -X POST https://correctover.com/api/v1/receipts \
      -H "authorization: Bearer cov_…" \
      -H "content-type: application/json" \
      -d '{"verdict":"DENY","tool":"shell.exec","correlation":"run-42"}'
    
    # 201
    # {"id":"9f2c…","status":"stored","used":1,"quota":50000,
    #  "note":"Stored. Attach CCS signature client-side or enable server signing."}
    verdict falls back to decision if you already use that field name, and defaults to UNKNOWN when neither is present. tool and correlation are optional but are what make a receipt joinable to your own traces. The full request body is stored with the receipt, so include what an auditor would need and nothing you would not hand them.
  4. Read usage. The same key and path with GET returns the workspace state used for quota decisions.
    curl https://correctover.com/api/v1/receipts \
      -H "authorization: Bearer cov_…"
    
    # 200
    # {"email":"[email protected]","plan":"starter","used":1,"quota":50000,"status":"active"}

Authentication

Send authorization: Bearer cov_…. Keys carry the cov_ prefix. Only a SHA-256 hash of the key is stored, so the plaintext key exists only in the response that revealed it.

A key is valid only while its workspace is active. Suspended or cancelled workspaces fail authentication even with a correct key.

Error codes

StatusCodeMeaning and action
400invalid_jsonBody was not parseable JSON. Fix the request; nothing was recorded.
400session_id_requiredClaim called without session_id.
400unknown_planPlan is not starter or team.
400email_requiredCheckout called without a billing email.
401unauthorizedMissing, malformed, revoked key, or inactive workspace.
402quota_exceededMonthly receipt quota reached. Existing receipts remain readable and verifiable.
404unknown_session / no_accountThe session id does not map to a workspace, or the workspace record is missing.
502stripe_errorPayment provider rejected the checkout request.
503not_configuredStorage is not bound for this deployment. Deployment-side issue, not a client error.

CORS and clients

All endpoints answer OPTIONS with access-control-allow-origin: *, methods GET, POST, OPTIONS, and headers content-type, authorization. A server job and a browser console call the same surface.

Because the origin is permissive, never embed a cov_ key in client-side code you ship to end users. Issue and use keys server-side.

Receipt shape

FieldSourceNotes
idGeneratedStable identifier for the stored receipt.
emailWorkspaceOwning workspace of the key used.
verdictverdict or decisionDefaults to UNKNOWN.
toolRequestTool or action name on the boundary.
correlationRequestYour trace or run id, for joining to your own logs.
payloadRequest bodyStored as sent.
created_atServerISO 8601 timestamp.

Operational notes

Quota is per workspace, per month

Counting happens on write. A rejected write over quota does not consume quota.

Signing is separate from storage

The write path stores the record. CCS signing is applied client-side, or server-side when a signing key is configured for the deployment.

Retention follows the tier

Export before the retention window closes if you need the receipts longer than the plan keeps them.

Need a workspace to test against?

Start trial View plans