CANDI API (1.0.0)

Download OpenAPI specification:

CANDI is a Merchant-of-Record billing platform (Creem.io parity): hosted checkout, subscriptions, license keys, customer credits, discounts, HMAC-signed webhooks and MoR payouts. This document is the CONTRACT — every parallel team builds against it. All monetary values are integer minor units (cents). Money is charged in USD and EUR only.

Authentication

Server-side only. Send your secret key in the x-api-key header. The key prefix selects the data plane: candi_live_... hits live, candi_test_... hits the fully isolated test environment (separate database). Keys are shown once at creation and stored only as a sha256 hash.

Errors

Every error returns the envelope {trace_id, status, error, message[], timestamp}. error is a stable machine-readable slug; message is a human-readable array.

Idempotency

Send an Idempotency-Key header on any POST/PUT/PATCH/DELETE to make it safe to retry — the original response is replayed for 24h. Reusing a key with a different body returns 409 idempotency_conflict. Customer-credit writes additionally require a durable idempotency_key field in the body.

Pagination

List/search endpoints accept page_number (default 1) and page_size (default 10).

Dual-mount (dashboard)

Every /v1/<resource> here is also served at /dashboard/v1/<resource> for the merchant dashboard, using the SAME schemas. The difference is auth + mode: the dashboard mount uses a session cookie (or bearer JWT) instead of x-api-key, and selects the live/test data plane via the x-candi-mode: live|test header instead of the key prefix. The dashboard also adds session-only reads not on the public API: /dashboard/v1/events, /dashboard/v1/stats/summary, /dashboard/v1/invoices and /dashboard/v1/api-keys.

Products

Create a product

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
name
required
string
description
string
image_url
string <uri>
price
required
integer <int64>

cents; 0 = free

currency
required
string (Currency)
Enum: "usd" "eur"
billing_type
required
string (BillingType)
Enum: "onetime" "recurring"
billing_period
string (BillingPeriod)
Enum: "once" "every-day" "every-month" "every-three-months" "every-six-months" "every-year"
tax_mode
string (TaxMode)
Enum: "inclusive" "exclusive"
tax_category
string (TaxCategory)
Enum: "saas" "digital-goods-service" "ebooks"
pay_what_you_want
boolean
suggested_price
integer <int64>
trial_days
integer
default_success_url
string <uri>

Responses

Response Schema: application/json
name
required
string
description
string
image_url
string <uri>
price
required
integer <int64>

cents; 0 = free

currency
required
string (Currency)
Enum: "usd" "eur"
billing_type
required
string (BillingType)
Enum: "onetime" "recurring"
billing_period
string (BillingPeriod)
Enum: "once" "every-day" "every-month" "every-three-months" "every-six-months" "every-year"
tax_mode
string (TaxMode)
Enum: "inclusive" "exclusive"
tax_category
string (TaxCategory)
Enum: "saas" "digital-goods-service" "ebooks"
pay_what_you_want
boolean
suggested_price
integer <int64>
trial_days
integer
default_success_url
string <uri>
id
string
mode
string
status
string
Enum: "active" "archived"
created_at
string <date-time>

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "image_url": "http://example.com",
  • "price": 0,
  • "currency": "usd",
  • "billing_type": "onetime",
  • "billing_period": "once",
  • "tax_mode": "inclusive",
  • "tax_category": "saas",
  • "pay_what_you_want": true,
  • "suggested_price": 0,
  • "trial_days": 0,
  • "default_success_url": "http://example.com"
}

Response samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "image_url": "http://example.com",
  • "price": 0,
  • "currency": "usd",
  • "billing_type": "onetime",
  • "billing_period": "once",
  • "tax_mode": "inclusive",
  • "tax_category": "saas",
  • "pay_what_you_want": true,
  • "suggested_price": 0,
  • "trial_days": 0,
  • "default_success_url": "http://example.com",
  • "id": "string",
  • "mode": "string",
  • "status": "active",
  • "created_at": "2019-08-24T14:15:22Z"
}

List products

Authorizations:
ApiKeyAuth
query Parameters
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array of objects (Product)
page_number
integer
page_size
integer
total
integer

Response samples

Content type
application/json
{
  • "items": [
    • {
      }
    ],
  • "page_number": 0,
  • "page_size": 0,
  • "total": 0
}

Search products

Authorizations:
ApiKeyAuth
query Parameters
query
string
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array of objects (Product)
page_number
integer
page_size
integer
total
integer

Response samples

Content type
application/json
{
  • "items": [
    • {
      }
    ],
  • "page_number": 0,
  • "page_size": 0,
  • "total": 0
}

Get a product

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Response Schema: application/json
name
required
string
description
string
image_url
string <uri>
price
required
integer <int64>

cents; 0 = free

currency
required
string (Currency)
Enum: "usd" "eur"
billing_type
required
string (BillingType)
Enum: "onetime" "recurring"
billing_period
string (BillingPeriod)
Enum: "once" "every-day" "every-month" "every-three-months" "every-six-months" "every-year"
tax_mode
string (TaxMode)
Enum: "inclusive" "exclusive"
tax_category
string (TaxCategory)
Enum: "saas" "digital-goods-service" "ebooks"
pay_what_you_want
boolean
suggested_price
integer <int64>
trial_days
integer
default_success_url
string <uri>
id
string
mode
string
status
string
Enum: "active" "archived"
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "image_url": "http://example.com",
  • "price": 0,
  • "currency": "usd",
  • "billing_type": "onetime",
  • "billing_period": "once",
  • "tax_mode": "inclusive",
  • "tax_category": "saas",
  • "pay_what_you_want": true,
  • "suggested_price": 0,
  • "trial_days": 0,
  • "default_success_url": "http://example.com",
  • "id": "string",
  • "mode": "string",
  • "status": "active",
  • "created_at": "2019-08-24T14:15:22Z"
}

Checkouts

Create a checkout session

Returns a session whose checkout_url is checkout.usecandi.com/{id}.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
product_id
required
string
units
integer >= 1
Default: 1
request_id
string
discount_code
string
pwyw_amount
integer <int64>
success_url
string <uri>
customer_email
string <email>
affiliate_ref
string
locale
string
theme
string
Enum: "light" "dark"
object
object

Values for the product's custom fields, keyed by field key. Every non-optional field must be present; unknown keys are rejected.

Responses

Response Schema: application/json
id
string
product_id
string
status
string
Enum: "pending" "completed" "expired"
checkout_url
string <uri>
units
integer
request_id
string
success_url
string <uri>
expires_at
string <date-time>
created_at
string <date-time>

Request samples

Content type
application/json
{
  • "product_id": "string",
  • "units": 1,
  • "request_id": "string",
  • "discount_code": "string",
  • "pwyw_amount": 0,
  • "success_url": "http://example.com",
  • "customer_email": "[email protected]",
  • "affiliate_ref": "string",
  • "locale": "string",
  • "theme": "light",
  • "metadata": { },
  • "custom_fields": { }
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "product_id": "string",
  • "status": "pending",
  • "checkout_url": "http://example.com",
  • "units": 0,
  • "request_id": "string",
  • "success_url": "http://example.com",
  • "expires_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z"
}

List checkout sessions

Authorizations:
ApiKeyAuth
query Parameters
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array of objects (Checkout)

Response samples

Content type
application/json
{
  • "items": [
    • {
      }
    ]
}

Get a checkout session

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Response Schema: application/json
id
string
product_id
string
status
string
Enum: "pending" "completed" "expired"
checkout_url
string <uri>
units
integer
request_id
string
success_url
string <uri>
expires_at
string <date-time>
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "id": "string",
  • "product_id": "string",
  • "status": "pending",
  • "checkout_url": "http://example.com",
  • "units": 0,
  • "request_id": "string",
  • "success_url": "http://example.com",
  • "expires_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z"
}

Orders

List orders

Orders are created by the platform when a checkout is paid; read-only.

Authorizations:
ApiKeyAuth
query Parameters
customer_id
string
product_id
string
status
string
Enum: "pending" "paid" "refunded" "partially_refunded" "chargeback" "failed"
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array of objects (Order)
page_number
integer
page_size
integer
total
integer

Response samples

Content type
application/json
{
  • "items": [
    • {
      }
    ],
  • "page_number": 0,
  • "page_size": 0,
  • "total": 0
}

Search orders

Authorizations:
ApiKeyAuth
query Parameters
customer_id
string
product_id
string
status
string
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array of objects (Order)
page_number
integer
page_size
integer
total
integer

Response samples

Content type
application/json
{
  • "items": [
    • {
      }
    ],
  • "page_number": 0,
  • "page_size": 0,
  • "total": 0
}

Get an order

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Response Schema: application/json
id
string
status
string
Enum: "pending" "paid" "refunded" "partially_refunded" "chargeback" "failed"
type
string
Enum: "onetime" "recurring"
customer_id
string
product_id
string
checkout_id
string
subscription_id
string
currency
string (Currency)
Enum: "usd" "eur"
sub_total
integer <int64>
tax_amount
integer <int64>
amount
integer <int64>

gross (sub_total + tax)

amount_paid
integer <int64>
amount_refunded
integer <int64>
fee_amount
integer <int64>

platform fee

net_amount
integer <int64>

amount - fee - tax (merchant credit)

transaction_id
string
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "id": "string",
  • "status": "pending",
  • "type": "onetime",
  • "customer_id": "string",
  • "product_id": "string",
  • "checkout_id": "string",
  • "subscription_id": "string",
  • "currency": "usd",
  • "sub_total": 0,
  • "tax_amount": 0,
  • "amount": 0,
  • "amount_paid": 0,
  • "amount_refunded": 0,
  • "fee_amount": 0,
  • "net_amount": 0,
  • "transaction_id": "string",
  • "created_at": "2019-08-24T14:15:22Z"
}

Subscriptions

List subscriptions

Authorizations:
ApiKeyAuth
query Parameters
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array of objects (Subscription)
page_number
integer
page_size
integer
total
integer

Response samples

Content type
application/json
{
  • "items": [
    • {
      }
    ],
  • "page_number": 0,
  • "page_size": 0,
  • "total": 0
}

Search subscriptions

Authorizations:
ApiKeyAuth
query Parameters
customer_id
string
product_id
string
status
string (SubscriptionStatus)
Enum: "trialing" "active" "paused" "past_due" "scheduled_cancel" "canceled" "expired"
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array of objects (Subscription)
page_number
integer
page_size
integer
total
integer

Response samples

Content type
application/json
{
  • "items": [
    • {
      }
    ],
  • "page_number": 0,
  • "page_size": 0,
  • "total": 0
}

Get a subscription

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Response Schema: application/json
id
string
customer_id
string
product_id
string
status
string (SubscriptionStatus)
Enum: "trialing" "active" "paused" "past_due" "scheduled_cancel" "canceled" "expired"
units
integer
current_period_start
string <date-time>
current_period_end
string <date-time>
next_transaction_date
string <date-time>
trial_end
string <date-time>
canceled_at
string <date-time>
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "id": "string",
  • "customer_id": "string",
  • "product_id": "string",
  • "status": "trialing",
  • "units": 0,
  • "current_period_start": "2019-08-24T14:15:22Z",
  • "current_period_end": "2019-08-24T14:15:22Z",
  • "next_transaction_date": "2019-08-24T14:15:22Z",
  • "trial_end": "2019-08-24T14:15:22Z",
  • "canceled_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z"
}

Update a subscription (seats/units)

Authorizations:
ApiKeyAuth
path Parameters
id
required
string
Request Body schema: application/json
units
integer >= 1

Responses

Response Schema: application/json
id
string
customer_id
string
product_id
string
status
string (SubscriptionStatus)
Enum: "trialing" "active" "paused" "past_due" "scheduled_cancel" "canceled" "expired"
units
integer
current_period_start
string <date-time>
current_period_end
string <date-time>
next_transaction_date
string <date-time>
trial_end
string <date-time>
canceled_at
string <date-time>
created_at
string <date-time>

Request samples

Content type
application/json
{
  • "units": 1
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "customer_id": "string",
  • "product_id": "string",
  • "status": "trialing",
  • "units": 0,
  • "current_period_start": "2019-08-24T14:15:22Z",
  • "current_period_end": "2019-08-24T14:15:22Z",
  • "next_transaction_date": "2019-08-24T14:15:22Z",
  • "trial_end": "2019-08-24T14:15:22Z",
  • "canceled_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z"
}

Upgrade/downgrade a subscription

Authorizations:
ApiKeyAuth
path Parameters
id
required
string
Request Body schema: application/json
required
product_id
required
string
units
integer >= 1
update_behavior
required
string (UpdateBehavior)
Enum: "proration-charge-immediately" "proration-charge" "proration-none"

Responses

Response Schema: application/json
id
string
customer_id
string
product_id
string
status
string (SubscriptionStatus)
Enum: "trialing" "active" "paused" "past_due" "scheduled_cancel" "canceled" "expired"
units
integer
current_period_start
string <date-time>
current_period_end
string <date-time>
next_transaction_date
string <date-time>
trial_end
string <date-time>
canceled_at
string <date-time>
created_at
string <date-time>

Request samples

Content type
application/json
{
  • "product_id": "string",
  • "units": 1,
  • "update_behavior": "proration-charge-immediately"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "customer_id": "string",
  • "product_id": "string",
  • "status": "trialing",
  • "units": 0,
  • "current_period_start": "2019-08-24T14:15:22Z",
  • "current_period_end": "2019-08-24T14:15:22Z",
  • "next_transaction_date": "2019-08-24T14:15:22Z",
  • "trial_end": "2019-08-24T14:15:22Z",
  • "canceled_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z"
}

Preview the proration for an upgrade/downgrade (no change applied)

Runs the same proration math as /upgrade without mutating the subscription, so the dashboard can show the exact immediate charge and next-invoice total before the merchant confirms. All amounts are int64 cents.

Authorizations:
ApiKeyAuth
path Parameters
id
required
string
Request Body schema: application/json
required
product_id
required
string
units
integer >= 1
update_behavior
required
string (UpdateBehavior)
Enum: "proration-charge-immediately" "proration-charge" "proration-none"

Responses

Response Schema: application/json
update_behavior
string (UpdateBehavior)
Enum: "proration-charge-immediately" "proration-charge" "proration-none"
currency
string
proration_amount
integer <int64>

Charged immediately (0 for charge/none; never negative).

credit_amount
integer <int64>

Unused current-plan time credited.

next_invoice_total
integer <int64>

Total at the next renewal.

next_renewal_at
string <date-time>
immediate
boolean

Request samples

Content type
application/json
{
  • "product_id": "string",
  • "units": 1,
  • "update_behavior": "proration-charge-immediately"
}

Response samples

Content type
application/json
{
  • "update_behavior": "proration-charge-immediately",
  • "currency": "string",
  • "proration_amount": 0,
  • "credit_amount": 0,
  • "next_invoice_total": 0,
  • "next_renewal_at": "2019-08-24T14:15:22Z",
  • "immediate": true
}

Cancel a subscription (immediate or at period end)

Authorizations:
ApiKeyAuth
path Parameters
id
required
string
Request Body schema: application/json
at_period_end
boolean
Default: false

Responses

Response Schema: application/json
id
string
customer_id
string
product_id
string
status
string (SubscriptionStatus)
Enum: "trialing" "active" "paused" "past_due" "scheduled_cancel" "canceled" "expired"
units
integer
current_period_start
string <date-time>
current_period_end
string <date-time>
next_transaction_date
string <date-time>
trial_end
string <date-time>
canceled_at
string <date-time>
created_at
string <date-time>

Request samples

Content type
application/json
{
  • "at_period_end": false
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "customer_id": "string",
  • "product_id": "string",
  • "status": "trialing",
  • "units": 0,
  • "current_period_start": "2019-08-24T14:15:22Z",
  • "current_period_end": "2019-08-24T14:15:22Z",
  • "next_transaction_date": "2019-08-24T14:15:22Z",
  • "trial_end": "2019-08-24T14:15:22Z",
  • "canceled_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z"
}

Pause a subscription

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Response Schema: application/json
id
string
customer_id
string
product_id
string
status
string (SubscriptionStatus)
Enum: "trialing" "active" "paused" "past_due" "scheduled_cancel" "canceled" "expired"
units
integer
current_period_start
string <date-time>
current_period_end
string <date-time>
next_transaction_date
string <date-time>
trial_end
string <date-time>
canceled_at
string <date-time>
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "id": "string",
  • "customer_id": "string",
  • "product_id": "string",
  • "status": "trialing",
  • "units": 0,
  • "current_period_start": "2019-08-24T14:15:22Z",
  • "current_period_end": "2019-08-24T14:15:22Z",
  • "next_transaction_date": "2019-08-24T14:15:22Z",
  • "trial_end": "2019-08-24T14:15:22Z",
  • "canceled_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z"
}

Resume a paused subscription

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Response Schema: application/json
id
string
customer_id
string
product_id
string
status
string (SubscriptionStatus)
Enum: "trialing" "active" "paused" "past_due" "scheduled_cancel" "canceled" "expired"
units
integer
current_period_start
string <date-time>
current_period_end
string <date-time>
next_transaction_date
string <date-time>
trial_end
string <date-time>
canceled_at
string <date-time>
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "id": "string",
  • "customer_id": "string",
  • "product_id": "string",
  • "status": "trialing",
  • "units": 0,
  • "current_period_start": "2019-08-24T14:15:22Z",
  • "current_period_end": "2019-08-24T14:15:22Z",
  • "next_transaction_date": "2019-08-24T14:15:22Z",
  • "trial_end": "2019-08-24T14:15:22Z",
  • "canceled_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z"
}

Customers

Create a customer

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
email
required
string <email>
name
string
country
string
tax_id
string
object

Responses

Response Schema: application/json
email
required
string <email>
name
string
country
string
tax_id
string
object
id
string
created_at
string <date-time>

Request samples

Content type
application/json
{
  • "email": "[email protected]",
  • "name": "string",
  • "country": "string",
  • "tax_id": "string",
  • "metadata": { }
}

Response samples

Content type
application/json
{
  • "email": "[email protected]",
  • "name": "string",
  • "country": "string",
  • "tax_id": "string",
  • "metadata": { },
  • "id": "string",
  • "created_at": "2019-08-24T14:15:22Z"
}

Update a customer

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
id
required
string
name
string
country
string
tax_id
string

Responses

Response Schema: application/json
email
required
string <email>
name
string
country
string
tax_id
string
object
id
string
created_at
string <date-time>

Request samples

Content type
application/json
{
  • "id": "string",
  • "name": "string",
  • "country": "string",
  • "tax_id": "string"
}

Response samples

Content type
application/json
{
  • "email": "[email protected]",
  • "name": "string",
  • "country": "string",
  • "tax_id": "string",
  • "metadata": { },
  • "id": "string",
  • "created_at": "2019-08-24T14:15:22Z"
}

List customers

Authorizations:
ApiKeyAuth
query Parameters
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array of objects (Customer)
page_number
integer
page_size
integer
total
integer

Response samples

Content type
application/json
{
  • "items": [
    • {
      }
    ],
  • "page_number": 0,
  • "page_size": 0,
  • "total": 0
}

Create a customer billing-portal magic link

Returns a one-time magic link to the customer billing portal (portal.usecandi.com) for the identified customer. Provide either customer_id or customer_email. The merchant redirects the customer to the link (and CANDI also emails it when email delivery is configured). The link is single-use and short-lived; exchanging it sets a portal session cookie.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
One of
customer_id
required
string
customer_email
string <email>

Responses

Response Schema: application/json
customer_portal_link
string <uri>

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{}

Get a customer

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Response Schema: application/json
email
required
string <email>
name
string
country
string
tax_id
string
object
id
string
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "email": "[email protected]",
  • "name": "string",
  • "country": "string",
  • "tax_id": "string",
  • "metadata": { },
  • "id": "string",
  • "created_at": "2019-08-24T14:15:22Z"
}

Transactions

List transactions

Authorizations:
ApiKeyAuth
query Parameters
customer_id
string
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array of objects (Transaction)
page_number
integer
page_size
integer
total
integer

Response samples

Content type
application/json
{
  • "items": [
    • {
      }
    ],
  • "page_number": 0,
  • "page_size": 0,
  • "total": 0
}

Get a transaction

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Response Schema: application/json
id
string
order_id
string
subscription_id
string
customer_id
string
status
string
Enum: "pending" "paid" "refunded" "chargeback"
currency
string (Currency)
Enum: "usd" "eur"
amount
integer <int64>
amount_paid
integer <int64>
amount_refunded
integer <int64>
tax_amount
integer <int64>
fee_amount
integer <int64>
tax_country
string
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "id": "string",
  • "order_id": "string",
  • "subscription_id": "string",
  • "customer_id": "string",
  • "status": "pending",
  • "currency": "usd",
  • "amount": 0,
  • "amount_paid": 0,
  • "amount_refunded": 0,
  • "tax_amount": 0,
  • "fee_amount": 0,
  • "tax_country": "string",
  • "created_at": "2019-08-24T14:15:22Z"
}

Licenses

Activate a license instance

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
key
required
string
instance_name
required
string

Responses

Response Schema: application/json
valid
boolean
key
string
status
string
Enum: "active" "inactive" "expired" "disabled"
activation_limit
integer
activation_count
integer
object

Request samples

Content type
application/json
{
  • "key": "string",
  • "instance_name": "string"
}

Response samples

Content type
application/json
{
  • "valid": true,
  • "key": "string",
  • "status": "active",
  • "activation_limit": 0,
  • "activation_count": 0,
  • "instance": {
    • "id": "string",
    • "name": "string"
    }
}

Validate a license (optionally a specific instance)

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
key
required
string
instance_id
string

Responses

Response Schema: application/json
valid
boolean
key
string
status
string
Enum: "active" "inactive" "expired" "disabled"
activation_limit
integer
activation_count
integer
object

Request samples

Content type
application/json
{
  • "key": "string",
  • "instance_id": "string"
}

Response samples

Content type
application/json
{
  • "valid": true,
  • "key": "string",
  • "status": "active",
  • "activation_limit": 0,
  • "activation_count": 0,
  • "instance": {
    • "id": "string",
    • "name": "string"
    }
}

Deactivate a license instance

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
key
required
string
instance_id
required
string

Responses

Response Schema: application/json
valid
boolean
key
string
status
string
Enum: "active" "inactive" "expired" "disabled"
activation_limit
integer
activation_count
integer
object

Request samples

Content type
application/json
{
  • "key": "string",
  • "instance_id": "string"
}

Response samples

Content type
application/json
{
  • "valid": true,
  • "key": "string",
  • "status": "active",
  • "activation_limit": 0,
  • "activation_count": 0,
  • "instance": {
    • "id": "string",
    • "name": "string"
    }
}

Discounts

Create a discount

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
name
required
string
code
required
string
type
required
string
Enum: "percentage" "fixed"
percentage
integer [ 0 .. 100 ]
amount
integer <int64>
currency
string (Currency)
Enum: "usd" "eur"
duration
string
Enum: "once" "forever" "repeating"
duration_in_months
integer
applies_to_products
Array of strings
expiry_date
string <date-time>
max_redemptions
integer

Responses

Response Schema: application/json
name
required
string
code
required
string
type
required
string
Enum: "percentage" "fixed"
percentage
integer [ 0 .. 100 ]
amount
integer <int64>
currency
string (Currency)
Enum: "usd" "eur"
duration
string
Enum: "once" "forever" "repeating"
duration_in_months
integer
applies_to_products
Array of strings
expiry_date
string <date-time>
max_redemptions
integer
id
string
redeem_count
integer
status
string
Enum: "active" "archived"
created_at
string <date-time>

Request samples

Content type
application/json
{
  • "name": "string",
  • "code": "string",
  • "type": "percentage",
  • "percentage": 100,
  • "amount": 0,
  • "currency": "usd",
  • "duration": "once",
  • "duration_in_months": 0,
  • "applies_to_products": [
    • "string"
    ],
  • "expiry_date": "2019-08-24T14:15:22Z",
  • "max_redemptions": 0
}

Response samples

Content type
application/json
{
  • "name": "string",
  • "code": "string",
  • "type": "percentage",
  • "percentage": 100,
  • "amount": 0,
  • "currency": "usd",
  • "duration": "once",
  • "duration_in_months": 0,
  • "applies_to_products": [
    • "string"
    ],
  • "expiry_date": "2019-08-24T14:15:22Z",
  • "max_redemptions": 0,
  • "id": "string",
  • "redeem_count": 0,
  • "status": "active",
  • "created_at": "2019-08-24T14:15:22Z"
}

List discounts

Authorizations:
ApiKeyAuth
query Parameters
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array of objects (Discount)

Response samples

Content type
application/json
{
  • "items": [
    • {
      }
    ]
}

Search discounts

Authorizations:
ApiKeyAuth
query Parameters
code
string

Responses

Response Schema: application/json
Array of objects (Discount)

Response samples

Content type
application/json
{
  • "items": [
    • {
      }
    ]
}

Get a discount

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Response Schema: application/json
name
required
string
code
required
string
type
required
string
Enum: "percentage" "fixed"
percentage
integer [ 0 .. 100 ]
amount
integer <int64>
currency
string (Currency)
Enum: "usd" "eur"
duration
string
Enum: "once" "forever" "repeating"
duration_in_months
integer
applies_to_products
Array of strings
expiry_date
string <date-time>
max_redemptions
integer
id
string
redeem_count
integer
status
string
Enum: "active" "archived"
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "name": "string",
  • "code": "string",
  • "type": "percentage",
  • "percentage": 100,
  • "amount": 0,
  • "currency": "usd",
  • "duration": "once",
  • "duration_in_months": 0,
  • "applies_to_products": [
    • "string"
    ],
  • "expiry_date": "2019-08-24T14:15:22Z",
  • "max_redemptions": 0,
  • "id": "string",
  • "redeem_count": 0,
  • "status": "active",
  • "created_at": "2019-08-24T14:15:22Z"
}

Delete (archive) a discount

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Credits

Create a credit account

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
customer_id
required
string
name
string
unit_label
string

Responses

Response Schema: application/json
id
string
customer_id
string
name
string
unit_label
string
status
string
Enum: "active" "frozen" "closed"
balance
integer <int64>
created_at
string <date-time>

Request samples

Content type
application/json
{
  • "customer_id": "string",
  • "name": "string",
  • "unit_label": "string"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "customer_id": "string",
  • "name": "string",
  • "unit_label": "string",
  • "status": "active",
  • "balance": 0,
  • "created_at": "2019-08-24T14:15:22Z"
}

List credit accounts

Authorizations:
ApiKeyAuth
query Parameters
customer_id
string
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array
id
string
customer_id
string
name
string
unit_label
string
status
string
Enum: "active" "frozen" "closed"
balance
integer <int64>
created_at
string <date-time>

Response samples

Content type
application/json
[
  • {
    • "id": "string",
    • "customer_id": "string",
    • "name": "string",
    • "unit_label": "string",
    • "status": "active",
    • "balance": 0,
    • "created_at": "2019-08-24T14:15:22Z"
    }
]

Get a credit account

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Response Schema: application/json
id
string
customer_id
string
name
string
unit_label
string
status
string
Enum: "active" "frozen" "closed"
balance
integer <int64>
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "id": "string",
  • "customer_id": "string",
  • "name": "string",
  • "unit_label": "string",
  • "status": "active",
  • "balance": 0,
  • "created_at": "2019-08-24T14:15:22Z"
}

Freeze a credit account

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Response Schema: application/json
id
string
customer_id
string
name
string
unit_label
string
status
string
Enum: "active" "frozen" "closed"
balance
integer <int64>
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "id": "string",
  • "customer_id": "string",
  • "name": "string",
  • "unit_label": "string",
  • "status": "active",
  • "balance": 0,
  • "created_at": "2019-08-24T14:15:22Z"
}

Unfreeze a credit account

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Response Schema: application/json
id
string
customer_id
string
name
string
unit_label
string
status
string
Enum: "active" "frozen" "closed"
balance
integer <int64>
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "id": "string",
  • "customer_id": "string",
  • "name": "string",
  • "unit_label": "string",
  • "status": "active",
  • "balance": 0,
  • "created_at": "2019-08-24T14:15:22Z"
}

Close a credit account

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Response Schema: application/json
id
string
customer_id
string
name
string
unit_label
string
status
string
Enum: "active" "frozen" "closed"
balance
integer <int64>
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "id": "string",
  • "customer_id": "string",
  • "name": "string",
  • "unit_label": "string",
  • "status": "active",
  • "balance": 0,
  • "created_at": "2019-08-24T14:15:22Z"
}

Credit an account

Authorizations:
ApiKeyAuth
path Parameters
id
required
string
Request Body schema: application/json
required
amount
required
integer <int64> >= 1
reference
required
string
idempotency_key
required
string

durable; dedupes the write

Responses

Response Schema: application/json
id
string
account_id
string
delta
integer <int64>
reference
string
idempotency_key
string
reversed_of
string
created_at
string <date-time>

Request samples

Content type
application/json
{
  • "amount": 1,
  • "reference": "string",
  • "idempotency_key": "string"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "account_id": "string",
  • "delta": 0,
  • "reference": "string",
  • "idempotency_key": "string",
  • "reversed_of": "string",
  • "created_at": "2019-08-24T14:15:22Z"
}

Debit an account

Authorizations:
ApiKeyAuth
path Parameters
id
required
string
Request Body schema: application/json
required
amount
required
integer <int64> >= 1
reference
required
string
idempotency_key
required
string

durable; dedupes the write

Responses

Response Schema: application/json
id
string
account_id
string
delta
integer <int64>
reference
string
idempotency_key
string
reversed_of
string
created_at
string <date-time>

Request samples

Content type
application/json
{
  • "amount": 1,
  • "reference": "string",
  • "idempotency_key": "string"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "account_id": "string",
  • "delta": 0,
  • "reference": "string",
  • "idempotency_key": "string",
  • "reversed_of": "string",
  • "created_at": "2019-08-24T14:15:22Z"
}

Reverse a prior credit entry

Authorizations:
ApiKeyAuth
path Parameters
id
required
string
Request Body schema: application/json
required
entry_id
required
string
idempotency_key
required
string

Responses

Response Schema: application/json
id
string
account_id
string
delta
integer <int64>
reference
string
idempotency_key
string
reversed_of
string
created_at
string <date-time>

Request samples

Content type
application/json
{
  • "entry_id": "string",
  • "idempotency_key": "string"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "account_id": "string",
  • "delta": 0,
  • "reference": "string",
  • "idempotency_key": "string",
  • "reversed_of": "string",
  • "created_at": "2019-08-24T14:15:22Z"
}

Get an account balance (optionally historical)

Authorizations:
ApiKeyAuth
path Parameters
id
required
string
query Parameters
at
string <date-time>

balance as of this instant

Responses

Response Schema: application/json
balance
integer <int64>
unit_label
string

Response samples

Content type
application/json
{
  • "balance": 0,
  • "unit_label": "string"
}

List credit entries

Authorizations:
ApiKeyAuth
path Parameters
id
required
string
query Parameters
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array
id
string
account_id
string
delta
integer <int64>
reference
string
idempotency_key
string
reversed_of
string
created_at
string <date-time>

Response samples

Content type
application/json
[
  • {
    • "id": "string",
    • "account_id": "string",
    • "delta": 0,
    • "reference": "string",
    • "idempotency_key": "string",
    • "reversed_of": "string",
    • "created_at": "2019-08-24T14:15:22Z"
    }
]

Stats

Aggregate stats

Authorizations:
ApiKeyAuth

Responses

Response Schema: application/json
total_revenue
integer <int64>

gross paid

transaction_count
integer
order_count
integer
customer_count
integer
mrr
integer <int64>

monthly recurring revenue

active_subscriptions
integer
currency
string (Currency)
Enum: "usd" "eur"

Response samples

Content type
application/json
{
  • "total_revenue": 0,
  • "transaction_count": 0,
  • "order_count": 0,
  • "customer_count": 0,
  • "mrr": 0,
  • "active_subscriptions": 0,
  • "currency": "usd"
}

MRR + revenue metrics (optional time series)

Authorizations:
ApiKeyAuth
query Parameters
interval
string
Enum: "day" "week" "month"

Responses

Response Schema: application/json
mrr
integer <int64>

monthly recurring revenue in cents

active_subscriptions
integer
Array of objects

Response samples

Content type
application/json
{
  • "mrr": 0,
  • "active_subscriptions": 0,
  • "periods": [
    • {
      }
    ]
}

Webhook Endpoints

Create a webhook endpoint

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
url
required
string <uri>
events
required
Array of strings (EventType)
Items Enum: "checkout.completed" "subscription.active" "subscription.paid" "subscription.canceled" "subscription.scheduled_cancel" "subscription.past_due" "subscription.expired" "subscription.trialing" "subscription.paused" "subscription.update" "refund.created" "dispute.created"

Responses

Response Schema: application/json
id
string
url
string <uri>
events
Array of strings (EventType)
Items Enum: "checkout.completed" "subscription.active" "subscription.paid" "subscription.canceled" "subscription.scheduled_cancel" "subscription.past_due" "subscription.expired" "subscription.trialing" "subscription.paused" "subscription.update" "refund.created" "dispute.created"
active
boolean
created_at
string <date-time>

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "id": "string",
  • "events": [
    • "checkout.completed"
    ],
  • "active": true,
  • "created_at": "2019-08-24T14:15:22Z"
}

List webhook endpoints

Authorizations:
ApiKeyAuth

Responses

Response Schema: application/json
Array
id
string
url
string <uri>
events
Array of strings (EventType)
Items Enum: "checkout.completed" "subscription.active" "subscription.paid" "subscription.canceled" "subscription.scheduled_cancel" "subscription.past_due" "subscription.expired" "subscription.trialing" "subscription.paused" "subscription.update" "refund.created" "dispute.created"
active
boolean
created_at
string <date-time>

Response samples

Content type
application/json
[
  • {
    • "id": "string",
    • "events": [
      ],
    • "active": true,
    • "created_at": "2019-08-24T14:15:22Z"
    }
]

Get a webhook endpoint

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Response Schema: application/json
id
string
url
string <uri>
events
Array of strings (EventType)
Items Enum: "checkout.completed" "subscription.active" "subscription.paid" "subscription.canceled" "subscription.scheduled_cancel" "subscription.past_due" "subscription.expired" "subscription.trialing" "subscription.paused" "subscription.update" "refund.created" "dispute.created"
active
boolean
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "id": "string",
  • "events": [
    • "checkout.completed"
    ],
  • "active": true,
  • "created_at": "2019-08-24T14:15:22Z"
}

Update a webhook endpoint

Authorizations:
ApiKeyAuth
path Parameters
id
required
string
Request Body schema: application/json
url
string <uri>
events
Array of strings (EventType)
Items Enum: "checkout.completed" "subscription.active" "subscription.paid" "subscription.canceled" "subscription.scheduled_cancel" "subscription.past_due" "subscription.expired" "subscription.trialing" "subscription.paused" "subscription.update" "refund.created" "dispute.created"
active
boolean

Responses

Response Schema: application/json
id
string
url
string <uri>
events
Array of strings (EventType)
Items Enum: "checkout.completed" "subscription.active" "subscription.paid" "subscription.canceled" "subscription.scheduled_cancel" "subscription.past_due" "subscription.expired" "subscription.trialing" "subscription.paused" "subscription.update" "refund.created" "dispute.created"
active
boolean
created_at
string <date-time>

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "id": "string",
  • "events": [
    • "checkout.completed"
    ],
  • "active": true,
  • "created_at": "2019-08-24T14:15:22Z"
}

Delete a webhook endpoint

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

List delivery attempts for an endpoint

Authorizations:
ApiKeyAuth
path Parameters
id
required
string
query Parameters
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array
id
string
endpoint_id
string
event_id
string
event_type
string (EventType)
Enum: "checkout.completed" "subscription.active" "subscription.paid" "subscription.canceled" "subscription.scheduled_cancel" "subscription.past_due" "subscription.expired" "subscription.trialing" "subscription.paused" "subscription.update" "refund.created" "dispute.created"
attempts
integer
status
string
Enum: "pending" "succeeded" "failed" "exhausted"
response_code
integer
next_retry_at
string <date-time>
created_at
string <date-time>

Response samples

Content type
application/json
[
  • {
    • "id": "string",
    • "endpoint_id": "string",
    • "event_id": "string",
    • "event_type": "checkout.completed",
    • "attempts": 0,
    • "status": "pending",
    • "response_code": 0,
    • "next_retry_at": "2019-08-24T14:15:22Z",
    • "created_at": "2019-08-24T14:15:22Z"
    }
]

Manually resend a delivery

Authorizations:
ApiKeyAuth
path Parameters
id
required
string
delivery_id
required
string

Responses

Revshare

Create a revenue split

Splits a product's (or the account's) net revenue to recipient CANDI accounts at settlement. A +2% platform fee applies to split transactions. Recipients accrue a normal merchant balance paid by the payout run.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
name
required
string
product_id
string or null

NULL = account-wide

Array of objects

Responses

Response Schema: application/json
id
string
name
string
product_id
string or null
status
string
Array of objects

Request samples

Content type
application/json
{
  • "name": "string",
  • "product_id": "string",
  • "recipients": [
    • {
      }
    ]
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "name": "string",
  • "product_id": "string",
  • "status": "string",
  • "recipients": [
    • {
      }
    ]
}

List revenue splits

Authorizations:
ApiKeyAuth
query Parameters
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Get a revenue split (with recipients)

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Response Schema: application/json
id
string
name
string
product_id
string or null
status
string
Array of objects

Response samples

Content type
application/json
{
  • "id": "string",
  • "name": "string",
  • "product_id": "string",
  • "status": "string",
  • "recipients": [
    • {
      }
    ]
}

Archive a revenue split

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Create an affiliate program

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
slug
required
string
commission_rate
integer

percent of net

cookie_days
integer
Default: 30
approval_required
boolean
public
boolean

Responses

Request samples

Content type
application/json
{
  • "slug": "string",
  • "commission_rate": 0,
  • "cookie_days": 30,
  • "approval_required": true,
  • "public": true
}

List affiliate programs

Authorizations:
ApiKeyAuth

Responses

Enroll an affiliate (returns the signed candi_ref token)

Authorizations:
ApiKeyAuth
path Parameters
id
required
string
Request Body schema: application/json
required
email
required
string
ref_code
string

generated when omitted

Responses

Request samples

Content type
application/json
{
  • "email": "string",
  • "ref_code": "string"
}

List a program's affiliates

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Approve or reject an affiliate

Authorizations:
ApiKeyAuth
path Parameters
id
required
string
Request Body schema: application/json
required
status
string
Enum: "approved" "rejected" "pending"

Responses

Request samples

Content type
application/json
{
  • "status": "approved"
}

List an affiliate's conversions

Authorizations:
ApiKeyAuth
path Parameters
id
required
string

Responses

Public

Get a checkout for the hosted checkout page

path Parameters
id
required
string

Responses

Response Schema: application/json
id
string
status
string
Enum: "pending" "completed" "expired"
account_name
string
object
units
integer
sub_total
integer <int64>
discount_code
string

applied discount code (present only when it re-priced)

discount_amount
integer <int64>

amount subtracted before tax

tax_amount
integer <int64>
total
integer <int64>
currency
string (Currency)
Enum: "usd" "eur"
Array of objects
theme
string
locale
string
stripe_publishable_key
string
prefill_email
string <email>
success_url
string <uri>
expires_at
string <date-time>

Response samples

Content type
application/json
{
  • "id": "string",
  • "status": "pending",
  • "account_name": "string",
  • "product": {
    • "name": "string",
    • "description": "string",
    • "image_url": "http://example.com",
    • "price": 0,
    • "currency": "usd",
    • "billing_type": "onetime",
    • "billing_period": "once",
    • "pay_what_you_want": true,
    • "suggested_price": 0
    },
  • "units": 0,
  • "sub_total": 0,
  • "discount_code": "string",
  • "discount_amount": 0,
  • "tax_amount": 0,
  • "total": 0,
  • "currency": "usd",
  • "custom_fields": [
    • {
      }
    ],
  • "theme": "string",
  • "locale": "string",
  • "stripe_publishable_key": "string",
  • "prefill_email": "[email protected]",
  • "success_url": "http://example.com",
  • "expires_at": "2019-08-24T14:15:22Z"
}

Create a PaymentIntent for the checkout (returns client_secret)

Re-derives the amount server-side from the stored session and creates a Stripe PaymentIntent, returning its client_secret for the Payment Element. The order and its paid state are created by the platform on the resulting payment_intent.succeeded webhook, not by this call.

path Parameters
id
required
string
Request Body schema: application/json
email
string <email>
pwyw_amount
integer <int64>

customer-chosen pay-what-you-want amount (cents)

object

values keyed by custom field key

Responses

Response Schema: application/json
client_secret
string
stripe_publishable_key
string
payment_intent_id
string
success_url
string <uri>

pass as stripe.confirmPayment return_url

amount
integer <int64>
currency
string (Currency)
Enum: "usd" "eur"

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "client_secret": "string",
  • "stripe_publishable_key": "string",
  • "payment_intent_id": "string",
  • "success_url": "http://example.com",
  • "amount": 0,
  • "currency": "usd"
}

Validate a discount code against a checkout (advisory, no redeem)

Evaluates a discount code for the pending checkout and returns the pre-tax amount off so the hosted page can show the savings before payment. It never mutates and never redeems; the authoritative re-price happens in confirm. For an inapplicable code it returns 200 with valid:false and a reason.

path Parameters
id
required
string
Request Body schema: application/json
required
code
required
string

Responses

Response Schema: application/json
valid
boolean
code
string
type
string
Enum: "percentage" "fixed"
amount_off
integer <int64>

cents off the pre-tax subtotal

currency
string (Currency)
Enum: "usd" "eur"
total_before
integer <int64>
reason
string
Enum: "not_found" "expired" "exhausted" "not_applicable_to_product" "currency_mismatch"
message
string

Request samples

Content type
application/json
{
  • "code": "string"
}

Response samples

Content type
application/json
{
  • "valid": true,
  • "code": "string",
  • "type": "percentage",
  • "amount_off": 0,
  • "currency": "usd",
  • "total_before": 0,
  • "reason": "not_found",
  • "message": "string"
}

Dashboard

Create an API key (raw key returned once)

Authorizations:
SessionCookieBearerAuth
Request Body schema: application/json
required
mode
required
string
Enum: "live" "test"
name
string
scopes
Array of strings

Responses

Response Schema: application/json
id
string
mode
string
Enum: "live" "test"
prefix
string

candi_live_ / candi_test_

last4
string
name
string
scopes
Array of strings
last_used_at
string <date-time>
revoked_at
string <date-time>
created_at
string <date-time>
key
string

the full secret — returned ONCE

Request samples

Content type
application/json
{
  • "mode": "live",
  • "name": "string",
  • "scopes": [
    • "string"
    ]
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "mode": "live",
  • "prefix": "string",
  • "last4": "string",
  • "name": "string",
  • "scopes": [
    • "string"
    ],
  • "last_used_at": "2019-08-24T14:15:22Z",
  • "revoked_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z",
  • "key": "string"
}

List API keys (both modes; prefix + last4 only)

Authorizations:
SessionCookieBearerAuth

Responses

Response Schema: application/json
Array
id
string
mode
string
Enum: "live" "test"
prefix
string

candi_live_ / candi_test_

last4
string
name
string
scopes
Array of strings
last_used_at
string <date-time>
revoked_at
string <date-time>
created_at
string <date-time>

Response samples

Content type
application/json
[
  • {
    • "id": "string",
    • "mode": "live",
    • "prefix": "string",
    • "last4": "string",
    • "name": "string",
    • "scopes": [
      ],
    • "last_used_at": "2019-08-24T14:15:22Z",
    • "revoked_at": "2019-08-24T14:15:22Z",
    • "created_at": "2019-08-24T14:15:22Z"
    }
]

Revoke an API key

Authorizations:
SessionCookieBearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "trace_id": "string",
  • "status": 0,
  • "error": "string",
  • "message": [
    • "string"
    ],
  • "timestamp": "2019-08-24T14:15:22Z"
}

List the account's invoices

Authorizations:
SessionCookieBearerAuth
query Parameters
mode
string
Default: "live"
Enum: "live" "test"
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array of objects (Invoice)
page_number
integer
page_size
integer
total
integer

Response samples

Content type
application/json
{
  • "items": [
    • {
      }
    ],
  • "page_number": 0,
  • "page_size": 0,
  • "total": 0
}

Get an invoice

Authorizations:
SessionCookieBearerAuth
path Parameters
id
required
string
query Parameters
mode
string
Default: "live"
Enum: "live" "test"

Responses

Response Schema: application/json
id
string
number
string

human number, e.g. INV-7Z9K2Q-00042

status
string
Enum: "pending" "rendered" "failed"
currency
string (Currency)
Enum: "usd" "eur"
sub_total
integer <int64>
tax_amount
integer <int64>
total
integer <int64>
customer_id
string
order_id
string
pdf_url
string <uri>

download URL once pdf_ready

pdf_ready
boolean
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "id": "string",
  • "number": "string",
  • "status": "pending",
  • "currency": "usd",
  • "sub_total": 0,
  • "tax_amount": 0,
  • "total": 0,
  • "customer_id": "string",
  • "order_id": "string",
  • "pdf_url": "http://example.com",
  • "pdf_ready": true,
  • "created_at": "2019-08-24T14:15:22Z"
}

Download an invoice PDF

Authorizations:
SessionCookieBearerAuth
path Parameters
id
required
string
query Parameters
mode
string
Default: "live"
Enum: "live" "test"

Responses

Response Schema: application/pdf
string <binary>

Response samples

Content type
application/json
{
  • "trace_id": "string",
  • "status": 0,
  • "error": "string",
  • "message": [
    • "string"
    ],
  • "timestamp": "2019-08-24T14:15:22Z"
}

List events

Authorizations:
SessionCookieBearerAuth
query Parameters
type
string (EventType)
Enum: "checkout.completed" "subscription.active" "subscription.paid" "subscription.canceled" "subscription.scheduled_cancel" "subscription.past_due" "subscription.expired" "subscription.trialing" "subscription.paused" "subscription.update" "refund.created" "dispute.created"
mode
string
Default: "live"
Enum: "live" "test"
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array of objects (Event)
page_number
integer
page_size
integer
total
integer

Response samples

Content type
application/json
{
  • "items": [
    • {
      }
    ],
  • "page_number": 0,
  • "page_size": 0,
  • "total": 0
}

Get an event

Authorizations:
SessionCookieBearerAuth
path Parameters
id
required
string
query Parameters
mode
string
Default: "live"
Enum: "live" "test"

Responses

Response Schema: application/json
id
string
type
string (EventType)
Enum: "checkout.completed" "subscription.active" "subscription.paid" "subscription.canceled" "subscription.scheduled_cancel" "subscription.past_due" "subscription.expired" "subscription.trialing" "subscription.paused" "subscription.update" "refund.created" "dispute.created"
mode
string
Enum: "prod" "test"
object
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "id": "string",
  • "type": "checkout.completed",
  • "mode": "prod",
  • "object": { },
  • "created_at": "2019-08-24T14:15:22Z"
}

Home stats summary (revenue, counts, MRR)

Authorizations:
SessionCookieBearerAuth
query Parameters
mode
string
Default: "live"
Enum: "live" "test"

Responses

Response Schema: application/json
total_revenue
integer <int64>

gross paid

transaction_count
integer
order_count
integer
customer_count
integer
mrr
integer <int64>

monthly recurring revenue

active_subscriptions
integer
currency
string (Currency)
Enum: "usd" "eur"

Response samples

Content type
application/json
{
  • "total_revenue": 0,
  • "transaction_count": 0,
  • "order_count": 0,
  • "customer_count": 0,
  • "mrr": 0,
  • "active_subscriptions": 0,
  • "currency": "usd"
}

Merchant ledger balances (held vs available)

Authorizations:
SessionCookieBearerAuth
query Parameters
mode
string
Default: "live"
Enum: "live" "test"

Responses

Response Schema: application/json
currency
string (Currency)
Enum: "usd" "eur"
merchant_held
integer <int64>

in the risk-hold window

merchant_available
integer <int64>

released

Response samples

Content type
application/json
{
  • "currency": "usd",
  • "merchant_held": 0,
  • "merchant_available": 0
}

Payout history

Authorizations:
SessionCookieBearerAuth
query Parameters
mode
string
Default: "live"
Enum: "live" "test"
page_number
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 10

Responses

Response Schema: application/json
Array of objects (Payout)
page_number
integer
page_size
integer
total
integer

Response samples

Content type
application/json
{
  • "items": [
    • {
      }
    ],
  • "page_number": 0,
  • "page_size": 0,
  • "total": 0
}

Portal

Exchange a magic-link token for a portal session (sets candi_portal cookie)

Request Body schema: application/json
required
token
required
string

Responses

Response Schema: application/json
object (PortalCustomer)

Request samples

Content type
application/json
{
  • "token": "string"
}

Response samples

Content type
application/json
{
  • "customer": {}
}

Revoke the current portal session and clear the cookie

Authorizations:
PortalCookie

Responses

The authenticated portal customer

Authorizations:
PortalCookie

Responses

Response Schema: application/json
id
string
email
string <email>
name
string
country
string

Response samples

Content type
application/json
{}

The customer's subscriptions (with product snapshot)

Authorizations:
PortalCookie

Responses

Response Schema: application/json
Array of objects (PortalSubscription)

Response samples

Content type
application/json
{
  • "items": [
    • {
      }
    ]
}

The customer's orders (paged)

Authorizations:
PortalCookie

Responses

The customer's invoices (empty until invoice generation lands)

Authorizations:
PortalCookie

Responses

Cancel (or schedule cancellation of) the customer's subscription

Authorizations:
PortalCookie
path Parameters
id
required
string
Request Body schema: application/json
optional
at_period_end
boolean

true = cancel at current period end

Responses

Response Schema: application/json
id
string
status
string (SubscriptionStatus)
Enum: "trialing" "active" "paused" "past_due" "scheduled_cancel" "canceled" "expired"
units
integer
object
current_period_start
string <date-time>
current_period_end
string <date-time>
next_transaction_date
string <date-time>
trial_end
string <date-time>
canceled_at
string <date-time>
has_payment_method
boolean
created_at
string <date-time>

Request samples

Content type
application/json
{
  • "at_period_end": true
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "status": "trialing",
  • "units": 0,
  • "product": {
    • "name": "string",
    • "price": 0,
    • "currency": "usd",
    • "billing_period": "once"
    },
  • "current_period_start": "2019-08-24T14:15:22Z",
  • "current_period_end": "2019-08-24T14:15:22Z",
  • "next_transaction_date": "2019-08-24T14:15:22Z",
  • "trial_end": "2019-08-24T14:15:22Z",
  • "canceled_at": "2019-08-24T14:15:22Z",
  • "has_payment_method": true,
  • "created_at": "2019-08-24T14:15:22Z"
}

Reverse a scheduled cancellation or resume a paused subscription

Authorizations:
PortalCookie
path Parameters
id
required
string

Responses

Response Schema: application/json
id
string
status
string (SubscriptionStatus)
Enum: "trialing" "active" "paused" "past_due" "scheduled_cancel" "canceled" "expired"
units
integer
object
current_period_start
string <date-time>
current_period_end
string <date-time>
next_transaction_date
string <date-time>
trial_end
string <date-time>
canceled_at
string <date-time>
has_payment_method
boolean
created_at
string <date-time>

Response samples

Content type
application/json
{
  • "id": "string",
  • "status": "trialing",
  • "units": 0,
  • "product": {
    • "name": "string",
    • "price": 0,
    • "currency": "usd",
    • "billing_period": "once"
    },
  • "current_period_start": "2019-08-24T14:15:22Z",
  • "current_period_end": "2019-08-24T14:15:22Z",
  • "next_transaction_date": "2019-08-24T14:15:22Z",
  • "trial_end": "2019-08-24T14:15:22Z",
  • "canceled_at": "2019-08-24T14:15:22Z",
  • "has_payment_method": true,
  • "created_at": "2019-08-24T14:15:22Z"
}

Start a SetupIntent to save a new default payment method

Authorizations:
PortalCookie
path Parameters
id
required
string

Responses

Response Schema: application/json
client_secret
string
stripe_publishable_key
string

Response samples

Content type
application/json
{
  • "client_secret": "string",
  • "stripe_publishable_key": "string"
}

checkout.completed Webhook

Sent when a checkout is paid and fulfilled. All 12 CANDI events share the WebhookEvent envelope; object holds the relevant entity (checkout, subscription, refund or dispute).

Signature (candi-signature header)

candi-signature: <hex> = HMAC_SHA256(rawBody, endpoint.secret), lower hex. Verify over the RAW request body (not a re-serialised copy). Retries fire at 30s, 1m, 5m, 1h; a manual resend is available from the dashboard. Never IP-allowlist — CANDI has no static source IPs. Dedupe on id.

Redirect signature (return URL)

On the customer's return to success_url, CANDI appends checkout_id, order_id, customer_id, subscription_id, product_id, request_id and signature. Verify: signature == SHA256hex("checkout_id={v}|order_id={v}|...|salt={apiKey}"), params in ARRIVAL order (not sorted), null/empty values excluded.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
id
required
string

event id (evt_...)

eventType
required
string (EventType)
Enum: "checkout.completed" "subscription.active" "subscription.paid" "subscription.canceled" "subscription.scheduled_cancel" "subscription.past_due" "subscription.expired" "subscription.trialing" "subscription.paused" "subscription.update" "refund.created" "dispute.created"
mode
required
string
Enum: "prod" "test" "local" "sandbox"
created_at
string <date-time>
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "eventType": "checkout.completed",
  • "mode": "prod",
  • "created_at": "2019-08-24T14:15:22Z",
  • "object": { }
}

subscription.* (active|paid|canceled|scheduled_cancel|past_due|expired|trialing|paused|update) Webhook

Authorizations:
ApiKeyAuth
Request Body schema: application/json
id
required
string

event id (evt_...)

eventType
required
string (EventType)
Enum: "checkout.completed" "subscription.active" "subscription.paid" "subscription.canceled" "subscription.scheduled_cancel" "subscription.past_due" "subscription.expired" "subscription.trialing" "subscription.paused" "subscription.update" "refund.created" "dispute.created"
mode
required
string
Enum: "prod" "test" "local" "sandbox"
created_at
string <date-time>
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "eventType": "checkout.completed",
  • "mode": "prod",
  • "created_at": "2019-08-24T14:15:22Z",
  • "object": { }
}

refund.created Webhook

Authorizations:
ApiKeyAuth
Request Body schema: application/json
id
required
string

event id (evt_...)

eventType
required
string (EventType)
Enum: "checkout.completed" "subscription.active" "subscription.paid" "subscription.canceled" "subscription.scheduled_cancel" "subscription.past_due" "subscription.expired" "subscription.trialing" "subscription.paused" "subscription.update" "refund.created" "dispute.created"
mode
required
string
Enum: "prod" "test" "local" "sandbox"
created_at
string <date-time>
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "eventType": "checkout.completed",
  • "mode": "prod",
  • "created_at": "2019-08-24T14:15:22Z",
  • "object": { }
}

dispute.created Webhook

Authorizations:
ApiKeyAuth
Request Body schema: application/json
id
required
string

event id (evt_...)

eventType
required
string (EventType)
Enum: "checkout.completed" "subscription.active" "subscription.paid" "subscription.canceled" "subscription.scheduled_cancel" "subscription.past_due" "subscription.expired" "subscription.trialing" "subscription.paused" "subscription.update" "refund.created" "dispute.created"
mode
required
string
Enum: "prod" "test" "local" "sandbox"
created_at
string <date-time>
required
object

Responses

Request samples

Content type
application/json
{
  • "id": "string",
  • "eventType": "checkout.completed",
  • "mode": "prod",
  • "created_at": "2019-08-24T14:15:22Z",
  • "object": { }
}