Redeem a partner access code
const url = 'http://localhost:8000/api/billing/access-code/redeem/';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"code":"ACME-7KQ4MX"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url http://localhost:8000/api/billing/access-code/redeem/ \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "code": "ACME-7KQ4MX" }'Owner-only. Puts the caller’s active team on the plan the code’s batch grants (e.g. Starter, 25 analyses, 183 days), with no card and no Stripe subscription. When the term ends the team returns to Free; its account and reports stay.
Errors (detail)
- 400
invalid— no such code, or it was revoked. - 400
expired— the code’s batch is closed or past its redeem-by date. - 400
email_not_verified— verify the sign-in email first. - 400
wrong_domain— the batch only accepts one email domain (e.g.alaska.edu); sign up with that address. - 400
unavailable— the code’s plan can’t be granted right now; nothing was spent. Contact support. - 409
already_used— the code was redeemed before. - 409
already_redeemed— this team’s previous code is still running. - 409
already_paid— the team is on a paid or complimentary plan already. - 403 — the caller does not own their active team.
Throttled per user.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
Examples
{ "code": "ACME-7KQ4MX"}object
Example generated
code=exampleobject
Responses
Section titled “Responses”object
Name of the granted plan.
Role of the granted plan (starter, pro, …); the key a client translates the plan name by.
Analyses for the whole term; they do not reset monthly.
When the team returns to the Free plan.
Examples
Access granted
{ "plan": "Starter", "role": "starter", "sessions": 25, "access_end": "2027-05-19T10:00:00Z"}object
Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).
Examples
Wrong email domain
{ "detail": "wrong_domain"}object
Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).
Example generated
{ "detail": "example"}object
Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).
Example generated
{ "detail": "example"}object
409 — the request conflicts with current state. detail is a stable code (e.g. reanalyze_in_flight, already_on_plan, email_in_use). Some 409s carry extra context fields alongside detail; those are documented on the specific endpoint that emits them.
Examples
Code already used
{ "detail": "already_used"}object
429 — rate limit exceeded. Honour the Retry-After response header (seconds to wait) before retrying; it is sent on every 429.
Example generated
{ "detail": "example"}