SUQODocs
User GuideAPI ReferenceSDKs

Errors

Error shapes that apply across the API, the auth failures every endpoint can return, and the per-endpoint 400s in one place.

Trailing slash required

Every route ends in / (e.g. /api/v1/subscriptions/).

  • A GET without the slash 301-redirects to the slashed URL.
  • A POST / write without the slash fails — the redirect can't preserve the request body.

Always include the trailing slash.

Error format

Field-specific validation errors return an object keyed by field name, with an array (or string) message:

{
  "field_name": ["Error message."]
}

General errors (auth failures, not found) return a detail key:

{
  "detail": "Error message."
}

Authentication and KYC

Returned by every endpoint. See Authenticate your requests.

StatusTriggerBody
401Missing / malformed / inactive key{"detail": "Invalid or inactive API key."}
403Owner not KYC-verified{"status_code": "<kyc_status>", "message": "KYC verification needed to perform this action."}

GET /api/v1/products/ is the exception to the 403: it works before KYC verification.

Creating a subscription

From Create a subscription.

StatusTriggerBody
400pbp_id unknown / not visible for this seller{"pbp_id": "PlanBillingPeriod with public_id '...' does not exist or is not visible."}
400Account has no API usage type{"api_usage_type": "Your account does not have an API usage type configured."}
400return_url missing{"return_url": "A return URL is required for reminder-and-payment accounts."}
400Active subscription already exists for this buyer + product + billing period{"detail": "An active subscription already exists for this buyer, product, and billing period."}

The last one only fires for a currently active subscription — an inactive or expired one is reused instead. See Reuse behaviour.

Managing a subscription

From Cancel or reschedule.

StatusTriggerBody
400Date in the past{"next_billing_cycle": ["next_billing_cycle must be in the future or today."]}
400Subscription not found / not owned{"subscription_id": "Subscription '...' does not exist."}

On this page