Start an organisation’s trial
const url = 'https://api.sloose.com/billing/admin/orgs/org_9f3c/trial';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"endsAt":"2026-11-30"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.sloose.com/billing/admin/orgs/org_9f3c/trial \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "endsAt": "2026-11-30" }'Backoffice route: a staff session, or ADMIN_TOKEN; never a customer’s session. The same eligibility rules as the customer-facing route — once per organisation, and no Stripe subscription, live at Stripe included — and the organisation’s open plan Checkouts are expired first, as there. Without a body it is the standard trial, Business for 14 days with 200 credits; endsAt ends it on a day staff choose, its credits scaled to its length — and more can be granted with POST /entitlements/admin/orgs/{orgId}/credits. A start is written down as org.trial, with the end chosen (endsOn, null for the standard trial), when it ends and the credits it grants.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The organisation id.
Example
org_9f3cThe organisation id.
Request Body
Section titled “Request Body”object
The day the trial ends on, YYYY-MM-DD: today or later and at most 90 days from today, in UTC. The trial runs through the end of that day in UTC, as an override’s expiry chosen in the backoffice does, and grants 200 credits for every 30 days of it begun: 200 up to 30 days, 400 up to 60. Omitted, null or empty, it is the standard trial: 14 days with 200 credits.
Example
2026-11-30Responses
Section titled “Responses”Not eligible, and which rule refused it.
object
Example
{ "started": false, "reason": "ORG_ALREADY_TRIALED"}Trial started.
object
When the trial ends, in UTC.
The AI credits it grants.
Example
{ "started": true}endsAt is not a calendar day written YYYY-MM-DD (TRIAL_END_NOT_A_DAY), is before today (TRIAL_END_PAST), or is more than 90 days from today (TRIAL_END_TOO_FAR), all in UTC; or a JSON body that is not an object (INVALID_BODY, with issues). An endsAt that is not text is TRIAL_END_NOT_A_DAY. Nothing is started. For the first three, error says which in the words the backoffice shows as the day is typed.
object
Example
{ "code": "TRIAL_END_NOT_A_DAY"}A bearer that is neither the token nor a live session (code: AUTH_REQUIRED).
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}A customer’s session, an API token, or no bearer at all — not staff, and not the ADMIN_TOKEN (code: ADMIN_REQUIRED).
The error envelope every non-2xx answer uses.
object
Human-readable explanation.
Machine-readable reason. Absent on a few legacy 400s.
Examplegenerated
{ "error": "example", "code": "example"}Stripe refused or was unavailable while the trial asked it whether the organisation pays already (PAYMENT_PROVIDER_REFUSED, PAYMENT_PROVIDER_UNAVAILABLE), and the trial did not start. Any open plan Checkout of the organisation closed before the failure stays closed: the trial closes them first, and a Checkout can be made again from Plan. Stripe’s own words are logged, not returned.
object
Example
{ "code": "PAYMENT_PROVIDER_REFUSED"}The restore switch is on (code: MAINTENANCE): every route but /health and /robots.txt is refused before anything is read, except the operator’s own POST /staff/people/{id}/delete with the ADMIN_TOKEN. Sloose is down for maintenance. Please try again in a few minutes.
object
Example
{ "code": "MAINTENANCE"}Headers
Section titled “Headers”Seconds until asking again is worth it (300 while the switch is on).