Start the trial clock

Stamp the rooftop's Receptionist subscription as activated, which starts the trial countdown. Call it right after the phone number is bought.

POSThttps://api.spyne.ai/agent-marketplace/billing/products/{productKey}/subscription/activate
AuthBearer token (console user); dealer group and rooftop are read from the tokenRate limitNot documentedProcessingSynchronousWarningActivates the subscription and starts the trial clock for the token's rooftop. Send an empty body; only call after the phone number purchase succeeds.

Spyne finds the rooftop's current subscription for the product and sets activated_at to now, but only if it is not already set. Calling it again returns the same subscription unchanged, so a retry cannot restart the countdown.

Auth: Bearer token of a signed-in user; the dealer group and rooftop are read from the token · Rate limit: not documented · Processing: synchronous

Before you call it

  • Call it after the phone number has been bought.
  • Use a token whose rooftop is the one going live. The call has no rooftop parameter.
  • If the rooftop has never had a subscription for this product, the call first enrolls it on the product's free plan, then stamps it.
  • If the rooftop had a subscription before that has since ended, for example expired or canceled, the call returns 404. That rule stops a second free trial.
  • Send an empty JSON object as the body. Fields are not read.

Path parameters

Requiredalways send
Request checklist
  1. Headers: set Authorization: Bearer YOUR_TOKEN and Content-Type: application/json.
  2. Body: send an empty JSON object.
  3. Read activated_at from the response.
  4. If it fails, keep going. The onboarding console treats this step as best-effort.
ParameterTypeRequiredDescription
productKeystringRequiredreceptionist_agent

Sample request

curl -X POST "https://api.spyne.ai/agent-marketplace/billing/products/receptionist_agent/subscription/activate" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
import requests

res = requests.post(
    "https://api.spyne.ai/agent-marketplace/billing/products/receptionist_agent/subscription/activate",
    headers={"Authorization": "Bearer YOUR_TOKEN"},
    json={},
)
print(res.status_code, res.json())
const res = await fetch(
  'https://api.spyne.ai/agent-marketplace/billing/products/receptionist_agent/subscription/activate',
  {
    method: 'POST',
    headers: {
      Authorization: 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({}),
  }
);
console.log(res.status, await res.json());

Sample response

{
  "id": "<subscriptionId>",
  "product_key": "receptionist_agent",
  "plan_key": "<planKey>",
  "status": "ACTIVE",
  "mrr_minor": "<amount>",
  "entitlements": {
    "meters": { "<meterKey>": { "limit": null, "period": "MONTH" } },
    "features": []
  },
  "current_period_start": "2026-10-12T15:04:05.000Z",
  "current_period_end": null,
  "cancel_requested_at": null,
  "activated_at": "2026-10-12T15:04:05.000Z"
}
{
  "message": "Authorization header must be a Bearer token",
  "error": "Unauthorized",
  "statusCode": 401,
  "code": "UNAUTHORIZED"
}
{
  "code": "TENANT_UNRESOLVED",
  "message": "Your account has no enterprise or rooftop associated with it, so this request cannot be scoped.",
  "statusCode": 403
}
{
  "code": "BILLING_SUBSCRIPTION_NOT_FOUND",
  "message": "No subscription for this rooftop on this product.",
  "statusCode": 404
}
{
  "code": "BILLING_SUBSCRIPTION_ALREADY_ACTIVE",
  "message": "This rooftop already has an active subscription for this product.",
  "statusCode": 409
}

Response parameters (200)

ParameterTypeDescription
idstringSubscription ID.
product_keystringreceptionist_agent.
plan_keystringCurrent plan key.
statusstringTRIALING, PENDING, ACTIVE, PAST_DUE, CANCELED or EXPIRED.
mrr_minornumberMonthly-normalized recurring amount in minor units.
entitlementsobjectSnapshot of the plan's entitlements.
current_period_startstring or nullISO timestamp.
current_period_endstring or nullISO timestamp. Billing-cycle end for a recurring plan, or the hard cutoff for a time-boxed plan. null when neither applies.
cancel_requested_atstring or nullISO timestamp of a pending cancellation.
activated_atstring or nullWhen the product was put into service. The trial countdown starts here.

Errors

StatusCodeWhen it happens
401UNAUTHORIZEDMissing or invalid Bearer token.
403TENANT_UNRESOLVEDThe token has no dealer group or rooftop.
404BILLING_SUBSCRIPTION_NOT_FOUNDThe rooftop has no current subscription but had one before. Also returned if a concurrent stamp happened and the subscription can no longer be found.
404BILLING_PRODUCT_NOT_FOUNDEnrollment was needed and the product key does not exist.
404BILLING_PLAN_NOT_FOUNDEnrollment was needed and the product has no free plan.
409BILLING_SUBSCRIPTION_ALREADY_ACTIVEEnrollment was needed and a parallel request created the subscription first.
500INTERNAL_ERRORUnexpected error.

What happens next

Call Grant the live product.

The onboarding console counts the trial as 14 days from activated_at, unless the subscription carries an enforced end date. That count is a screen rule, not something this API enforces.


Did this page help you?