API reference
Billing and data export
/ v1/ hooks/ billing/ checkoutsPay first: starts a checkout for someone without an account (the payment page's /start, from the website and sign-up): planId, optional interval (2 years by default) and email to prefill. Answers checkoutId, url and the secret the payment page keeps in the browser's cookie; the checkout opens only with it (x-checkout-secret). 429 past 20 an hour per address.
- Auth
- None.
Request body
planIdstringrequiredMatches
^[a-z0-9][a-z0-9-]{1,62}$.interval"two-year" | "year" | "month"emailstringUp to 254 characters.
Errors
429Too many attempts. Try again in an hour.
curl -X POST 'https://api.cactive.com.au/v1/hooks/billing/checkouts' \
-H 'Content-Type: application/json' \
-d '{
"planId": "<planId>"
}'Response 201
{
checkoutId: string
secret: string
url: string
}/ v1/ hooks/ billing/ checkouts/ :checkoutIdA pay-first checkout, priced from plan data, for the browser holding its secret (x-checkout-secret; anyone else gets 404); once paid, the sign-up's next step.
- Auth
- None.
Path parameters
checkoutIdA checkout's id on the payment page (
chk_…).
curl 'https://api.cactive.com.au/v1/hooks/billing/checkouts/{checkoutId}'Response 200
{
checkoutId: string
kind: "card" | "invoice" | "subscribe"
status: "canceled" | "expired" | "failed" | "open" | "action" | "complete" | "processing"
app: string
ownerType: "user" | "org"
ownerId: string
ownerName?: string
currency: string
plan?: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}
interval?: "month" | "two-year" | "year"
intervals: ("month" | "two-year" | "year")[]
seats: number
unit?: number
amount?: number
gst?: number
trial?: {
days: number
endsAt: number
}
dueToday: number
invoice?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
account: {
billingName?: string
billingEmail?: string
taxId?: string
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
}
promotion?: {
code: string
discount: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
amount: number
discountedAmount: number
charges: number | "all"
nextCharge?: {
total: number
discount: number
tax?: number
}
dueToday: number
endsAt?: number
}
provider: {
name: string
mode: string
publishableKey?: string
}
returnUrl: string
cancelUrl: string
openUntil: number
outcome?: {
status?: string
invoiceId?: string
trialEndsAt?: number
message?: string
amount?: number
}
receipt?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
referenceRates?: {
base: "aud"
rates: {
usd: number
nzd: number
gbp: number
eur: number
}
asOf: string
}
guest?: boolean
email?: string
signup?: {
signupId: string
audience: "personal" | "business"
planId: string
planName?: string
next: "invite" | "done" | "account" | "pay" | "details" | "secure"
email?: string
orgName?: string
orgSlug?: string
orgId?: string
}
}/ v1/ hooks/ billing/ checkouts/ :checkoutId/ startBefore the card: the email (required; Stripe Link's field) and interval, then a setup intent for the card fields (cards and Link). An email that already paid and hasn't finished gets its link again (409); a person's email that already has a plan is told to sign in (409).
- Auth
- None.
Path parameters
checkoutIdA checkout's id on the payment page (
chk_…).
Request body
interval"two-year" | "year" | "month"emailstringUp to 254 characters.
billingAddressobjectbillingAddress.line1stringrequired1–200 characters. Trimmed.
billingAddress.line2stringUp to 200 characters. Trimmed.
billingAddress.citystringUp to 100 characters. Trimmed.
billingAddress.statestringUp to 100 characters. Trimmed.
billingAddress.postalCodestringUp to 20 characters. Trimmed.
billingAddress.countrystringrequiredMatches
^[A-Z]{2}$.
Errors
429Too many attempts. Try again in an hour.
curl -X POST 'https://api.cactive.com.au/v1/hooks/billing/checkouts/{checkoutId}/start' \
-H 'Content-Type: application/json' \
-d '{
"interval": "two-year",
"email": "person@example.com",
"billingAddress": {
"line1": "example",
"country": "example"
}
}'Response 200
{
checkout: {
checkoutId: string
kind: "card" | "invoice" | "subscribe"
status: "canceled" | "expired" | "failed" | "open" | "action" | "complete" | "processing"
app: string
ownerType: "user" | "org"
ownerId: string
ownerName?: string
currency: string
plan?: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}
interval?: "month" | "two-year" | "year"
intervals: ("month" | "two-year" | "year")[]
seats: number
unit?: number
amount?: number
gst?: number
trial?: {
days: number
endsAt: number
}
dueToday: number
invoice?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
account: {
billingName?: string
billingEmail?: string
taxId?: string
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
}
promotion?: {
code: string
discount: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
amount: number
discountedAmount: number
charges: number | "all"
nextCharge?: {
total: number
discount: number
tax?: number
}
dueToday: number
endsAt?: number
}
provider: {
name: string
mode: string
publishableKey?: string
}
returnUrl: string
cancelUrl: string
openUntil: number
outcome?: {
status?: string
invoiceId?: string
trialEndsAt?: number
message?: string
amount?: number
}
receipt?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
referenceRates?: {
base: "aud"
rates: {
usd: number
nzd: number
gbp: number
eur: number
}
asOf: string
}
guest?: boolean
email?: string
signup?: {
signupId: string
audience: "personal" | "business"
planId: string
planName?: string
next: "invite" | "done" | "account" | "pay" | "details" | "secure"
email?: string
orgName?: string
orgSlug?: string
orgId?: string
}
}
setup: {
setupIntentId: string
clientSecret: string
provider: string
mode: string
publishableKey?: string
}
}/ v1/ hooks/ billing/ checkouts/ :checkoutId/ completeWith the card confirmed: starts the plan (its free trial included) for a pending organization (business) or the sign-up (personal), and emails "Finish setting up" with a single-use link. action.clientSecret when the bank wants the first payment confirmed; then confirm.
- Auth
- None.
Path parameters
checkoutIdA checkout's id on the payment page (
chk_…).
Request body
setupIntentIdstringrequiredMatches
^[A-Za-z0-9_]{3,255}$.
curl -X POST 'https://api.cactive.com.au/v1/hooks/billing/checkouts/{checkoutId}/complete' \
-H 'Content-Type: application/json' \
-d '{
"setupIntentId": "<setupIntentId>"
}'Response 200
{
checkout: {
checkoutId: string
kind: "card" | "invoice" | "subscribe"
status: "canceled" | "expired" | "failed" | "open" | "action" | "complete" | "processing"
app: string
ownerType: "user" | "org"
ownerId: string
ownerName?: string
currency: string
plan?: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}
interval?: "month" | "two-year" | "year"
intervals: ("month" | "two-year" | "year")[]
seats: number
unit?: number
amount?: number
gst?: number
trial?: {
days: number
endsAt: number
}
dueToday: number
invoice?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
account: {
billingName?: string
billingEmail?: string
taxId?: string
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
}
promotion?: {
code: string
discount: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
amount: number
discountedAmount: number
charges: number | "all"
nextCharge?: {
total: number
discount: number
tax?: number
}
dueToday: number
endsAt?: number
}
provider: {
name: string
mode: string
publishableKey?: string
}
returnUrl: string
cancelUrl: string
openUntil: number
outcome?: {
status?: string
invoiceId?: string
trialEndsAt?: number
message?: string
amount?: number
}
receipt?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
referenceRates?: {
base: "aud"
rates: {
usd: number
nzd: number
gbp: number
eur: number
}
asOf: string
}
guest?: boolean
email?: string
signup?: {
signupId: string
audience: "personal" | "business"
planId: string
planName?: string
next: "invite" | "done" | "account" | "pay" | "details" | "secure"
email?: string
orgName?: string
orgSlug?: string
orgId?: string
}
}
action?: {
clientSecret: string
}
}/ v1/ hooks/ billing/ checkouts/ :checkoutId/ confirmAfter the bank's confirmation in the browser: the first payment as the provider now has it, and the checkout complete or failed.
- Auth
- None.
Path parameters
checkoutIdA checkout's id on the payment page (
chk_…).
Request body
localApprovalboolean
curl -X POST 'https://api.cactive.com.au/v1/hooks/billing/checkouts/{checkoutId}/confirm' \
-H 'Content-Type: application/json' \
-d '{
"localApproval": true
}'Response 200
{
checkout: {
checkoutId: string
kind: "card" | "invoice" | "subscribe"
status: "canceled" | "expired" | "failed" | "open" | "action" | "complete" | "processing"
app: string
ownerType: "user" | "org"
ownerId: string
ownerName?: string
currency: string
plan?: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}
interval?: "month" | "two-year" | "year"
intervals: ("month" | "two-year" | "year")[]
seats: number
unit?: number
amount?: number
gst?: number
trial?: {
days: number
endsAt: number
}
dueToday: number
invoice?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
account: {
billingName?: string
billingEmail?: string
taxId?: string
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
}
promotion?: {
code: string
discount: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
amount: number
discountedAmount: number
charges: number | "all"
nextCharge?: {
total: number
discount: number
tax?: number
}
dueToday: number
endsAt?: number
}
provider: {
name: string
mode: string
publishableKey?: string
}
returnUrl: string
cancelUrl: string
openUntil: number
outcome?: {
status?: string
invoiceId?: string
trialEndsAt?: number
message?: string
amount?: number
}
receipt?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
referenceRates?: {
base: "aud"
rates: {
usd: number
nzd: number
gbp: number
eur: number
}
asOf: string
}
guest?: boolean
email?: string
signup?: {
signupId: string
audience: "personal" | "business"
planId: string
planName?: string
next: "invite" | "done" | "account" | "pay" | "details" | "secure"
email?: string
orgName?: string
orgSlug?: string
orgId?: string
}
}
action?: {
clientSecret: string
}
}/ v1/ hooks/ billing/ checkouts/ :checkoutId/ code"Have a code?" on a pay-first checkout, as for a signed-in one; the email given so far is checked against codes for one buyer (and again with the card). 429 past billing.promoChecksPerHour an hour per address.
- Auth
- None.
Path parameters
checkoutIdA checkout's id on the payment page (
chk_…).
Request body
codestringrequiredor null1–60 characters. Trimmed.
interval"two-year" | "year" | "month"emailstringUp to 254 characters.
Errors
429Too many codes tried. Try again in an hour.
curl -X POST 'https://api.cactive.com.au/v1/hooks/billing/checkouts/{checkoutId}/code' \
-H 'Content-Type: application/json' \
-d '{
"code": "example"
}'Response 200
{
checkoutId: string
kind: "card" | "invoice" | "subscribe"
status: "canceled" | "expired" | "failed" | "open" | "action" | "complete" | "processing"
app: string
ownerType: "user" | "org"
ownerId: string
ownerName?: string
currency: string
plan?: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}
interval?: "month" | "two-year" | "year"
intervals: ("month" | "two-year" | "year")[]
seats: number
unit?: number
amount?: number
gst?: number
trial?: {
days: number
endsAt: number
}
dueToday: number
invoice?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
account: {
billingName?: string
billingEmail?: string
taxId?: string
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
}
promotion?: {
code: string
discount: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
amount: number
discountedAmount: number
charges: number | "all"
nextCharge?: {
total: number
discount: number
tax?: number
}
dueToday: number
endsAt?: number
}
provider: {
name: string
mode: string
publishableKey?: string
}
returnUrl: string
cancelUrl: string
openUntil: number
outcome?: {
status?: string
invoiceId?: string
trialEndsAt?: number
message?: string
amount?: number
}
receipt?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
referenceRates?: {
base: "aud"
rates: {
usd: number
nzd: number
gbp: number
eur: number
}
asOf: string
}
guest?: boolean
email?: string
signup?: {
signupId: string
audience: "personal" | "business"
planId: string
planName?: string
next: "invite" | "done" | "account" | "pay" | "details" | "secure"
email?: string
orgName?: string
orgSlug?: string
orgId?: string
}
}/ v1/ hooks/ billing/ checkouts/ :checkoutId/ finishAfter paying: the organization's name (orgName, business) and the email (Stripe's by default). Answers next: account with a url that hands the browser to ID to make the account and sign in, or next: email when the email already has an account (only the emailed link opens it). A changed email voids the links sent before and gets a new one.
- Auth
- None.
Path parameters
checkoutIdA checkout's id on the payment page (
chk_…).
Request body
orgNamestringUp to 200 characters.
emailstringUp to 254 characters.
Errors
429Too many attempts. Try again in an hour.
curl -X POST 'https://api.cactive.com.au/v1/hooks/billing/checkouts/{checkoutId}/finish' \
-H 'Content-Type: application/json' \
-d '{
"orgName": "Example",
"email": "person@example.com"
}'Response 200
{
checkout: {
checkoutId: string
kind: "card" | "invoice" | "subscribe"
status: "canceled" | "expired" | "failed" | "open" | "action" | "complete" | "processing"
app: string
ownerType: "user" | "org"
ownerId: string
ownerName?: string
currency: string
plan?: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}
interval?: "month" | "two-year" | "year"
intervals: ("month" | "two-year" | "year")[]
seats: number
unit?: number
amount?: number
gst?: number
trial?: {
days: number
endsAt: number
}
dueToday: number
invoice?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
account: {
billingName?: string
billingEmail?: string
taxId?: string
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
}
promotion?: {
code: string
discount: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
amount: number
discountedAmount: number
charges: number | "all"
nextCharge?: {
total: number
discount: number
tax?: number
}
dueToday: number
endsAt?: number
}
provider: {
name: string
mode: string
publishableKey?: string
}
returnUrl: string
cancelUrl: string
openUntil: number
outcome?: {
status?: string
invoiceId?: string
trialEndsAt?: number
message?: string
amount?: number
}
receipt?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
referenceRates?: {
base: "aud"
rates: {
usd: number
nzd: number
gbp: number
eur: number
}
asOf: string
}
guest?: boolean
email?: string
signup?: {
signupId: string
audience: "personal" | "business"
planId: string
planName?: string
next: "invite" | "done" | "account" | "pay" | "details" | "secure"
email?: string
orgName?: string
orgSlug?: string
orgId?: string
}
}
next: "email" | "account"
url?: string
sentTo?: string
}/ v1/ hooks/ billing/ checkouts/ :checkoutId/ cancelCloses a pay-first checkout and answers where to go back to.
- Auth
- None.
Path parameters
checkoutIdA checkout's id on the payment page (
chk_…).
curl -X POST 'https://api.cactive.com.au/v1/hooks/billing/checkouts/{checkoutId}/cancel'Response 200
{
returnUrl: string
}/ v1/ hooks/ billing/ signups/ resendEmails a new "Finish setting up" link for the newest unfinished pay-first sign-up of email. Always 202, whether or not there is one; 429 past 10 an hour per address or 3 per email.
- Auth
- None.
Request body
emailstringrequiredUp to 254 characters.
Errors
429Too many attempts. Try again in an hour.
curl -X POST 'https://api.cactive.com.au/v1/hooks/billing/signups/resend' \
-H 'Content-Type: application/json' \
-d '{
"email": "person@example.com"
}'Response 202
{
ok: true
}/ v1/ hooks/ billing/ stripeStripe's webhooks. The raw body is verified against Stripe-Signature (HMAC-SHA256, five minutes) and each event is applied once; the object is fetched fresh from Stripe. 400 when it doesn't verify, 409 while the same event is being handled elsewhere (Stripe retries). No authentication.
- Auth
- None.
Errors
413Too large500Webhook failed
curl -X POST 'https://api.cactive.com.au/v1/hooks/billing/stripe'/ v1/ orgs/ :orgId/ billingThe organization's Cactive One subscription: plan, status, seats, trial and period ends, the card's brand and last four digits, billing details, whether it's subsidised and whether its apps can be used now (access), the plans it can choose, the retention period and the seats a subscription would bill now. tenant:read; answers even when the organization's access has ended.
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:read
Path parameters
orgIdOrganization id (
org_…).
curl 'https://api.cactive.com.au/v1/orgs/{orgId}/billing' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 200
{
account: {
ownerId: string
ownerType: "user" | "org"
provider: string
mode: "local" | "live" | "test"
planId?: string
planName?: string
interval?: "month" | "two-year" | "year"
status: "active" | "none" | "canceled" | "incomplete" | "trialing" | "past_due" | "unpaid"
seats?: number
trialEndsAt?: number
periodEndsAt?: number
trialUsed: boolean
canceledAt?: number
accessEndedAt?: number
retainUntil?: number
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingName?: string
billingEmail?: string
taxId?: string
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
discount?: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
subsidised?: boolean
subsidy?: {
planId: string
planName?: string
since: number
until?: number
}
personalPlan?: {
planId?: string
via: "subsidised" | "subscription" | "free"
}
access?: {
state: "full"
via: "platform" | "subsidised" | "legacy" | "subscription"
} | {
state: "ended"
reason: "canceled" | "unpaid" | "setup"
}
}
plans: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}[]
retentionDays: number
provider: {
name: string
mode: string
publishableKey?: string
}
seatsNow?: number
}/ v1/ orgs/ :orgId/ billing/ checkoutStarts a checkout on the payment page (payments.<host>) and answers its url, checkoutId and openUntil. kind: subscribe (a business plan, planId, and interval: two-year by default, year or month; the plan's trial applies once per organization; 409 when there's already a subscription), card (replace the card) or invoice (pay an open invoice, invoiceId). returnUrl must be on Tenant's host (400 otherwise); the page sends the person back there with ?checkout=<id>&status=complete or canceled. Owners and administrators (tenant:write); 429 past 20 checkouts an hour.
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:write
Path parameters
orgIdOrganization id (
org_…).
Request body
kind"subscribe" | "card" | "invoice"requiredplanIdstringMatches
^[a-z0-9][a-z0-9-]{1,62}$.interval"two-year" | "year" | "month"invoiceIdstringMatches
^[A-Za-z0-9_]{3,255}$.returnUrlstringrequiredUp to 2,000 characters. URL.
Errors
403Billing needs a signed-in person.429Too many attempts. Try again in an hour.
curl -X POST 'https://api.cactive.com.au/v1/orgs/{orgId}/billing/checkout' \
-H "Authorization: Bearer $CACTIVE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"kind": "subscribe",
"returnUrl": "https://example.com"
}'Response 201
{
checkoutId: string
url: string
openUntil: number
}/ v1/ orgs/ :orgId/ billing/ planMoves the subscription to another plan (planId) or billing period (interval: two-year, year or month) now. Within the same period the difference is prorated onto the next invoice; a new period starts today and is charged now, less the unused part of the current one (402 when declined; nothing changes). Nothing is charged during a trial.
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:write
Path parameters
orgIdOrganization id (
org_…).
Request body
planIdstringrequiredMatches
^[a-z0-9][a-z0-9-]{1,62}$.interval"two-year" | "year" | "month"required
curl -X POST 'https://api.cactive.com.au/v1/orgs/{orgId}/billing/plan' \
-H "Authorization: Bearer $CACTIVE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"planId": "<planId>",
"interval": "two-year"
}'Response 200
{
account: {
ownerId: string
ownerType: "user" | "org"
provider: string
mode: "local" | "live" | "test"
planId?: string
planName?: string
interval?: "month" | "two-year" | "year"
status: "active" | "none" | "canceled" | "incomplete" | "trialing" | "past_due" | "unpaid"
seats?: number
trialEndsAt?: number
periodEndsAt?: number
trialUsed: boolean
canceledAt?: number
accessEndedAt?: number
retainUntil?: number
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingName?: string
billingEmail?: string
taxId?: string
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
discount?: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
subsidised?: boolean
subsidy?: {
planId: string
planName?: string
since: number
until?: number
}
personalPlan?: {
planId?: string
via: "subsidised" | "subscription" | "free"
}
access?: {
state: "full"
via: "platform" | "subsidised" | "legacy" | "subscription"
} | {
state: "ended"
reason: "canceled" | "unpaid" | "setup"
}
}
plans: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}[]
retentionDays: number
provider: {
name: string
mode: string
publishableKey?: string
}
seatsNow?: number
}/ v1/ orgs/ :orgId/ billing/ detailsSets who invoices are addressed and emailed to and the ABN shown on tax invoices (taxId: null removes it).
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:write
Path parameters
orgIdOrganization id (
org_…).
Request body
billingNamestring1–200 characters. Trimmed.
billingEmailstringUp to 254 characters. Email address.
taxIdstringUp to 40 characters. Trimmed.
billingAddressobjectbillingAddress.line1stringrequired1–200 characters. Trimmed.
billingAddress.line2stringUp to 200 characters. Trimmed.
billingAddress.citystringUp to 100 characters. Trimmed.
billingAddress.statestringUp to 100 characters. Trimmed.
billingAddress.postalCodestringUp to 20 characters. Trimmed.
billingAddress.countrystringrequiredMatches
^[A-Z]{2}$.taxIdany JSONrequiredor null
curl -X PATCH 'https://api.cactive.com.au/v1/orgs/{orgId}/billing/details' \
-H "Authorization: Bearer $CACTIVE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"taxId": {}
}'Response 200
{
account: {
ownerId: string
ownerType: "user" | "org"
provider: string
mode: "local" | "live" | "test"
planId?: string
planName?: string
interval?: "month" | "two-year" | "year"
status: "active" | "none" | "canceled" | "incomplete" | "trialing" | "past_due" | "unpaid"
seats?: number
trialEndsAt?: number
periodEndsAt?: number
trialUsed: boolean
canceledAt?: number
accessEndedAt?: number
retainUntil?: number
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingName?: string
billingEmail?: string
taxId?: string
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
discount?: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
subsidised?: boolean
subsidy?: {
planId: string
planName?: string
since: number
until?: number
}
personalPlan?: {
planId?: string
via: "subsidised" | "subscription" | "free"
}
access?: {
state: "full"
via: "platform" | "subsidised" | "legacy" | "subscription"
} | {
state: "ended"
reason: "canceled" | "unpaid" | "setup"
}
}
plans: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}[]
retentionDays: number
provider: {
name: string
mode: string
publishableKey?: string
}
seatsNow?: number
}/ v1/ orgs/ :orgId/ billing/ cancelCancels now: the organization's apps close at once (billing, exports and administration stay), nothing more is charged and the period already paid isn't refunded. The data is kept for the retention period (retainUntil), for export or resubscribing.
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:write
Path parameters
orgIdOrganization id (
org_…).
curl -X POST 'https://api.cactive.com.au/v1/orgs/{orgId}/billing/cancel' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 200
{
account: {
ownerId: string
ownerType: "user" | "org"
provider: string
mode: "local" | "live" | "test"
planId?: string
planName?: string
interval?: "month" | "two-year" | "year"
status: "active" | "none" | "canceled" | "incomplete" | "trialing" | "past_due" | "unpaid"
seats?: number
trialEndsAt?: number
periodEndsAt?: number
trialUsed: boolean
canceledAt?: number
accessEndedAt?: number
retainUntil?: number
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingName?: string
billingEmail?: string
taxId?: string
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
discount?: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
subsidised?: boolean
subsidy?: {
planId: string
planName?: string
since: number
until?: number
}
personalPlan?: {
planId?: string
via: "subsidised" | "subscription" | "free"
}
access?: {
state: "full"
via: "platform" | "subsidised" | "legacy" | "subscription"
} | {
state: "ended"
reason: "canceled" | "unpaid" | "setup"
}
}
plans: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}[]
retentionDays: number
provider: {
name: string
mode: string
publishableKey?: string
}
seatsNow?: number
}/ v1/ orgs/ :orgId/ billing/ code/ previewWhat a promotion code (code) would do to the running subscription, before adding it: checked (active, not expired, redemptions left, the plans, billing periods and buyer it's for, first payment only, a minimum order), then priced: each charge before and after, how many are discounted, when it ends, and the next invoice as the payment provider works it out. 400 says why a code can't be used; 429 past billing.promoChecksPerHour codes an hour.
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:write
Path parameters
orgIdOrganization id (
org_…).
Request body
codestringrequired1–60 characters. Trimmed.
Errors
403Billing needs a signed-in person.429Too many codes tried. Try again in an hour.
curl -X POST 'https://api.cactive.com.au/v1/orgs/{orgId}/billing/code/preview' \
-H "Authorization: Bearer $CACTIVE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"code": "example"
}'Response 200
{
code: string
discount: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
amount: number
discountedAmount: number
charges: number | "all"
nextCharge?: {
total: number
discount: number
tax?: number
}
dueToday: number
endsAt?: number
}/ v1/ orgs/ :orgId/ billing/ codeAdds a promotion code to the running subscription, in place of any discount it had, from its next invoice. Answers the billing overview with account.discount. tenant:write; in the audit log.
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:write
Path parameters
orgIdOrganization id (
org_…).
Request body
codestringrequired1–60 characters. Trimmed.
Errors
403Billing needs a signed-in person.429Too many codes tried. Try again in an hour.
curl -X POST 'https://api.cactive.com.au/v1/orgs/{orgId}/billing/code' \
-H "Authorization: Bearer $CACTIVE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"code": "example"
}'Response 200
{
account: {
ownerId: string
ownerType: "user" | "org"
provider: string
mode: "local" | "live" | "test"
planId?: string
planName?: string
interval?: "month" | "two-year" | "year"
status: "active" | "none" | "canceled" | "incomplete" | "trialing" | "past_due" | "unpaid"
seats?: number
trialEndsAt?: number
periodEndsAt?: number
trialUsed: boolean
canceledAt?: number
accessEndedAt?: number
retainUntil?: number
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingName?: string
billingEmail?: string
taxId?: string
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
discount?: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
subsidised?: boolean
subsidy?: {
planId: string
planName?: string
since: number
until?: number
}
personalPlan?: {
planId?: string
via: "subsidised" | "subscription" | "free"
}
access?: {
state: "full"
via: "platform" | "subsidised" | "legacy" | "subscription"
} | {
state: "ended"
reason: "canceled" | "unpaid" | "setup"
}
}
plans: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}[]
retentionDays: number
provider: {
name: string
mode: string
publishableKey?: string
}
seatsNow?: number
}/ v1/ orgs/ :orgId/ billing/ codeTakes the promotion code off the subscription: its next invoices are at the full price. In the audit log.
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:write
Path parameters
orgIdOrganization id (
org_…).
curl -X DELETE 'https://api.cactive.com.au/v1/orgs/{orgId}/billing/code' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 200
{
account: {
ownerId: string
ownerType: "user" | "org"
provider: string
mode: "local" | "live" | "test"
planId?: string
planName?: string
interval?: "month" | "two-year" | "year"
status: "active" | "none" | "canceled" | "incomplete" | "trialing" | "past_due" | "unpaid"
seats?: number
trialEndsAt?: number
periodEndsAt?: number
trialUsed: boolean
canceledAt?: number
accessEndedAt?: number
retainUntil?: number
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingName?: string
billingEmail?: string
taxId?: string
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
discount?: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
subsidised?: boolean
subsidy?: {
planId: string
planName?: string
since: number
until?: number
}
personalPlan?: {
planId?: string
via: "subsidised" | "subscription" | "free"
}
access?: {
state: "full"
via: "platform" | "subsidised" | "legacy" | "subscription"
} | {
state: "ended"
reason: "canceled" | "unpaid" | "setup"
}
}
plans: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}[]
retentionDays: number
provider: {
name: string
mode: string
publishableKey?: string
}
seatsNow?: number
}/ v1/ orgs/ :orgId/ billing/ invoicesThe organization's invoices, newest first, with totals and the GST included.
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:read
Path parameters
orgIdOrganization id (
org_…).
curl 'https://api.cactive.com.au/v1/orgs/{orgId}/billing/invoices' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 200
{
invoices: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}[]
}/ v1/ orgs/ :orgId/ billing/ invoices/ :invoiceIdOne tax invoice: lines, total, GST included, the buyer's details as issued and the supplier's name and ABN.
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:read
Path parameters
orgIdOrganization id (
org_…).invoiceIdAn invoice's id (the payment provider's,
in_…).
curl 'https://api.cactive.com.au/v1/orgs/{orgId}/billing/invoices/{invoiceId}' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 200
{
invoice: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
}/ v1/ orgs/ :orgId/ exportsRecent exports with their progress and, once ready, each ZIP's download link (a day).
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:write
Path parameters
orgIdOrganization id (
org_…).
Errors
403Exports are made by a person signed in.
curl 'https://api.cactive.com.au/v1/orgs/{orgId}/exports' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 200
{
exports: {
exportId: string
status: "queued" | "ready" | "failed" | "running"
requestedBy: string
files: number
bytes: number
sections: {
app: string
label: string
files: number
records?: number
note?: string
}[]
createdAt: number
expiresAt: number
error?: string
archives: {
archiveId: string
name: string
status: string
files: number
bytes: number
url?: string
}[]
}[]
}/ v1/ orgs/ :orgId/ exportsStarts a full export of the organization's data: every app's records as JSON and CSV, mail as .eml, calendars as .ics, contacts as .vcf, and its Drive files, as ZIPs kept a day with a README of what's in them. One at a time per organization (409 otherwise). Owners and administrators; works after the subscription ends.
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:write
Path parameters
orgIdOrganization id (
org_…).
Errors
403Exports are made by a person signed in.404Export not found409An export is already being made. Wait for it to finish.
curl -X POST 'https://api.cactive.com.au/v1/orgs/{orgId}/exports' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 201
{
export: {
exportId: string
status: "queued" | "ready" | "failed" | "running"
requestedBy: string
files: number
bytes: number
sections: {
app: string
label: string
files: number
records?: number
note?: string
}[]
createdAt: number
expiresAt: number
error?: string
archives: {
archiveId: string
name: string
status: string
files: number
bytes: number
url?: string
}[]
}
}/ v1/ orgs/ :orgId/ exports/ :exportIdOne export: its progress, what each app contributed and its ZIPs' download links.
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:write
Path parameters
orgIdOrganization id (
org_…).exportIdAn export's id (
pex_…for Photos,oex_…for an organization).
Errors
403Exports are made by a person signed in.404Export not found
curl 'https://api.cactive.com.au/v1/orgs/{orgId}/exports/{exportId}' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 200
{
export: {
exportId: string
status: "queued" | "ready" | "failed" | "running"
requestedBy: string
files: number
bytes: number
sections: {
app: string
label: string
files: number
records?: number
note?: string
}[]
createdAt: number
expiresAt: number
error?: string
archives: {
archiveId: string
name: string
status: string
files: number
bytes: number
url?: string
}[]
}
}/ v1/ me/ billingYour Cactive One Personal plan (storage for Drive and Photos), its status and card, and the personal plans you can choose. Free unless you subscribe.
- Auth
- A person's token or an API key, as Authorization: Bearer.
Errors
403Billing needs a signed-in person.
curl 'https://api.cactive.com.au/v1/me/billing' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 200
{
account: {
ownerId: string
ownerType: "user" | "org"
provider: string
mode: "local" | "live" | "test"
planId?: string
planName?: string
interval?: "month" | "two-year" | "year"
status: "active" | "none" | "canceled" | "incomplete" | "trialing" | "past_due" | "unpaid"
seats?: number
trialEndsAt?: number
periodEndsAt?: number
trialUsed: boolean
canceledAt?: number
accessEndedAt?: number
retainUntil?: number
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingName?: string
billingEmail?: string
taxId?: string
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
discount?: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
subsidised?: boolean
subsidy?: {
planId: string
planName?: string
since: number
until?: number
}
personalPlan?: {
planId?: string
via: "subsidised" | "subscription" | "free"
}
access?: {
state: "full"
via: "platform" | "subsidised" | "legacy" | "subscription"
} | {
state: "ended"
reason: "canceled" | "unpaid" | "setup"
}
}
plans: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}[]
retentionDays: number
provider: {
name: string
mode: string
publishableKey?: string
}
seatsNow?: number
}/ v1/ me/ billing/ joined/ :orgIdThe person just joined this organisation (on the web: an invite, a join code): its billed seats follow at once, as they do when Tenant or the phone adds someone (seatsChanged), rather than at the nightly reconcile. Only for a member now.
- Auth
- A person's token or an API key, as Authorization: Bearer.
Path parameters
orgIdOrganization id (
org_…).
Errors
403Billing needs a signed-in person.404You're not in that organisation.
curl -X POST 'https://api.cactive.com.au/v1/me/billing/joined/{orgId}' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 204 with no body
/ v1/ me/ billing/ checkoutStarts a checkout on the payment page for your own plan (Pro and Max start with a 14-day trial, once), your card or an open invoice, as for an organization. returnUrl must be on your account's host.
- Auth
- A person's token or an API key, as Authorization: Bearer.
Request body
kind"subscribe" | "card" | "invoice"requiredplanIdstringMatches
^[a-z0-9][a-z0-9-]{1,62}$.interval"two-year" | "year" | "month"invoiceIdstringMatches
^[A-Za-z0-9_]{3,255}$.returnUrlstringrequiredUp to 2,000 characters. URL.
Errors
403Billing needs a signed-in person.429Too many attempts. Try again in an hour.
curl -X POST 'https://api.cactive.com.au/v1/me/billing/checkout' \
-H "Authorization: Bearer $CACTIVE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"kind": "subscribe",
"returnUrl": "https://example.com"
}'Response 201
{
checkoutId: string
url: string
openUntil: number
}/ v1/ me/ billing/ planMoves your personal plan to another tier or billing period, as for an organization.
- Auth
- A person's token or an API key, as Authorization: Bearer.
Request body
planIdstringrequiredMatches
^[a-z0-9][a-z0-9-]{1,62}$.interval"two-year" | "year" | "month"required
Errors
403Billing needs a signed-in person.
curl -X POST 'https://api.cactive.com.au/v1/me/billing/plan' \
-H "Authorization: Bearer $CACTIVE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"planId": "<planId>",
"interval": "two-year"
}'Response 200
{
account: {
ownerId: string
ownerType: "user" | "org"
provider: string
mode: "local" | "live" | "test"
planId?: string
planName?: string
interval?: "month" | "two-year" | "year"
status: "active" | "none" | "canceled" | "incomplete" | "trialing" | "past_due" | "unpaid"
seats?: number
trialEndsAt?: number
periodEndsAt?: number
trialUsed: boolean
canceledAt?: number
accessEndedAt?: number
retainUntil?: number
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingName?: string
billingEmail?: string
taxId?: string
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
discount?: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
subsidised?: boolean
subsidy?: {
planId: string
planName?: string
since: number
until?: number
}
personalPlan?: {
planId?: string
via: "subsidised" | "subscription" | "free"
}
access?: {
state: "full"
via: "platform" | "subsidised" | "legacy" | "subscription"
} | {
state: "ended"
reason: "canceled" | "unpaid" | "setup"
}
}
plans: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}[]
retentionDays: number
provider: {
name: string
mode: string
publishableKey?: string
}
seatsNow?: number
}/ v1/ me/ billing/ detailsSets the name and email on your invoices.
- Auth
- A person's token or an API key, as Authorization: Bearer.
Request body
billingNamestring1–200 characters. Trimmed.
billingEmailstringUp to 254 characters. Email address.
taxIdstringUp to 40 characters. Trimmed.
billingAddressobjectbillingAddress.line1stringrequired1–200 characters. Trimmed.
billingAddress.line2stringUp to 200 characters. Trimmed.
billingAddress.citystringUp to 100 characters. Trimmed.
billingAddress.statestringUp to 100 characters. Trimmed.
billingAddress.postalCodestringUp to 20 characters. Trimmed.
billingAddress.countrystringrequiredMatches
^[A-Z]{2}$.taxIdany JSONrequiredor null
Errors
403Billing needs a signed-in person.
curl -X PATCH 'https://api.cactive.com.au/v1/me/billing/details' \
-H "Authorization: Bearer $CACTIVE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"taxId": {}
}'Response 200
{
account: {
ownerId: string
ownerType: "user" | "org"
provider: string
mode: "local" | "live" | "test"
planId?: string
planName?: string
interval?: "month" | "two-year" | "year"
status: "active" | "none" | "canceled" | "incomplete" | "trialing" | "past_due" | "unpaid"
seats?: number
trialEndsAt?: number
periodEndsAt?: number
trialUsed: boolean
canceledAt?: number
accessEndedAt?: number
retainUntil?: number
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingName?: string
billingEmail?: string
taxId?: string
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
discount?: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
subsidised?: boolean
subsidy?: {
planId: string
planName?: string
since: number
until?: number
}
personalPlan?: {
planId?: string
via: "subsidised" | "subscription" | "free"
}
access?: {
state: "full"
via: "platform" | "subsidised" | "legacy" | "subscription"
} | {
state: "ended"
reason: "canceled" | "unpaid" | "setup"
}
}
plans: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}[]
retentionDays: number
provider: {
name: string
mode: string
publishableKey?: string
}
seatsNow?: number
}/ v1/ me/ billing/ cancelCancels your personal plan now: storage returns to the free allowance (your files stay; over it you can view and download but not add).
- Auth
- A person's token or an API key, as Authorization: Bearer.
Errors
403Billing needs a signed-in person.
curl -X POST 'https://api.cactive.com.au/v1/me/billing/cancel' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 200
{
account: {
ownerId: string
ownerType: "user" | "org"
provider: string
mode: "local" | "live" | "test"
planId?: string
planName?: string
interval?: "month" | "two-year" | "year"
status: "active" | "none" | "canceled" | "incomplete" | "trialing" | "past_due" | "unpaid"
seats?: number
trialEndsAt?: number
periodEndsAt?: number
trialUsed: boolean
canceledAt?: number
accessEndedAt?: number
retainUntil?: number
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingName?: string
billingEmail?: string
taxId?: string
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
discount?: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
subsidised?: boolean
subsidy?: {
planId: string
planName?: string
since: number
until?: number
}
personalPlan?: {
planId?: string
via: "subsidised" | "subscription" | "free"
}
access?: {
state: "full"
via: "platform" | "subsidised" | "legacy" | "subscription"
} | {
state: "ended"
reason: "canceled" | "unpaid" | "setup"
}
}
plans: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}[]
retentionDays: number
provider: {
name: string
mode: string
publishableKey?: string
}
seatsNow?: number
}/ v1/ me/ billing/ code/ previewWhat a promotion code (code) would do to your plan, before adding it, as for an organization.
- Auth
- A person's token or an API key, as Authorization: Bearer.
Request body
codestringrequired1–60 characters. Trimmed.
Errors
403Billing needs a signed-in person.429Too many codes tried. Try again in an hour.
curl -X POST 'https://api.cactive.com.au/v1/me/billing/code/preview' \
-H "Authorization: Bearer $CACTIVE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"code": "example"
}'Response 200
{
code: string
discount: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
amount: number
discountedAmount: number
charges: number | "all"
nextCharge?: {
total: number
discount: number
tax?: number
}
dueToday: number
endsAt?: number
}/ v1/ me/ billing/ codeAdds a promotion code to your plan, from its next invoice.
- Auth
- A person's token or an API key, as Authorization: Bearer.
Request body
codestringrequired1–60 characters. Trimmed.
Errors
403Billing needs a signed-in person.429Too many codes tried. Try again in an hour.
curl -X POST 'https://api.cactive.com.au/v1/me/billing/code' \
-H "Authorization: Bearer $CACTIVE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"code": "example"
}'Response 200
{
account: {
ownerId: string
ownerType: "user" | "org"
provider: string
mode: "local" | "live" | "test"
planId?: string
planName?: string
interval?: "month" | "two-year" | "year"
status: "active" | "none" | "canceled" | "incomplete" | "trialing" | "past_due" | "unpaid"
seats?: number
trialEndsAt?: number
periodEndsAt?: number
trialUsed: boolean
canceledAt?: number
accessEndedAt?: number
retainUntil?: number
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingName?: string
billingEmail?: string
taxId?: string
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
discount?: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
subsidised?: boolean
subsidy?: {
planId: string
planName?: string
since: number
until?: number
}
personalPlan?: {
planId?: string
via: "subsidised" | "subscription" | "free"
}
access?: {
state: "full"
via: "platform" | "subsidised" | "legacy" | "subscription"
} | {
state: "ended"
reason: "canceled" | "unpaid" | "setup"
}
}
plans: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}[]
retentionDays: number
provider: {
name: string
mode: string
publishableKey?: string
}
seatsNow?: number
}/ v1/ me/ billing/ codeTakes the promotion code off your plan.
- Auth
- A person's token or an API key, as Authorization: Bearer.
Errors
403Billing needs a signed-in person.
curl -X DELETE 'https://api.cactive.com.au/v1/me/billing/code' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 200
{
account: {
ownerId: string
ownerType: "user" | "org"
provider: string
mode: "local" | "live" | "test"
planId?: string
planName?: string
interval?: "month" | "two-year" | "year"
status: "active" | "none" | "canceled" | "incomplete" | "trialing" | "past_due" | "unpaid"
seats?: number
trialEndsAt?: number
periodEndsAt?: number
trialUsed: boolean
canceledAt?: number
accessEndedAt?: number
retainUntil?: number
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingName?: string
billingEmail?: string
taxId?: string
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
discount?: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
subsidised?: boolean
subsidy?: {
planId: string
planName?: string
since: number
until?: number
}
personalPlan?: {
planId?: string
via: "subsidised" | "subscription" | "free"
}
access?: {
state: "full"
via: "platform" | "subsidised" | "legacy" | "subscription"
} | {
state: "ended"
reason: "canceled" | "unpaid" | "setup"
}
}
plans: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}[]
retentionDays: number
provider: {
name: string
mode: string
publishableKey?: string
}
seatsNow?: number
}/ v1/ me/ billing/ invoicesYour personal plan's invoices.
- Auth
- A person's token or an API key, as Authorization: Bearer.
Errors
403Billing needs a signed-in person.
curl 'https://api.cactive.com.au/v1/me/billing/invoices' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 200
{
invoices: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}[]
}/ v1/ me/ billing/ invoices/ :invoiceIdOne of your tax invoices.
- Auth
- A person's token or an API key, as Authorization: Bearer.
Path parameters
invoiceIdAn invoice's id (the payment provider's,
in_…).
Errors
403Billing needs a signed-in person.
curl 'https://api.cactive.com.au/v1/me/billing/invoices/{invoiceId}' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 200
{
invoice: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
}/ v1/ me/ checkouts/ :checkoutIdA checkout you started, as the payment page shows it: what's being bought, priced from plan data (the plan, the interval and the intervals it can switch to, seats, the amount, GST, what's due today, the trial), or the invoice; your billing details; the publishable key for the card fields; the way back; and once done, the outcome and the receipt. Anyone else gets 404.
- Auth
- A person's token or an API key, as Authorization: Bearer.
Path parameters
checkoutIdA checkout's id on the payment page (
chk_…).
Errors
403Billing needs a signed-in person.404Checkout not found
curl 'https://api.cactive.com.au/v1/me/checkouts/{checkoutId}' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 200
{
checkoutId: string
kind: "card" | "invoice" | "subscribe"
status: "canceled" | "expired" | "failed" | "open" | "action" | "complete" | "processing"
app: string
ownerType: "user" | "org"
ownerId: string
ownerName?: string
currency: string
plan?: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}
interval?: "month" | "two-year" | "year"
intervals: ("month" | "two-year" | "year")[]
seats: number
unit?: number
amount?: number
gst?: number
trial?: {
days: number
endsAt: number
}
dueToday: number
invoice?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
account: {
billingName?: string
billingEmail?: string
taxId?: string
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
}
promotion?: {
code: string
discount: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
amount: number
discountedAmount: number
charges: number | "all"
nextCharge?: {
total: number
discount: number
tax?: number
}
dueToday: number
endsAt?: number
}
provider: {
name: string
mode: string
publishableKey?: string
}
returnUrl: string
cancelUrl: string
openUntil: number
outcome?: {
status?: string
invoiceId?: string
trialEndsAt?: number
message?: string
amount?: number
}
receipt?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
referenceRates?: {
base: "aud"
rates: {
usd: number
nzd: number
gbp: number
eur: number
}
asOf: string
}
guest?: boolean
email?: string
signup?: {
signupId: string
audience: "personal" | "business"
planId: string
planName?: string
next: "invite" | "done" | "account" | "pay" | "details" | "secure"
email?: string
orgName?: string
orgSlug?: string
orgId?: string
}
}/ v1/ me/ checkouts/ :checkoutId/ startBefore the card: sets the billing period (interval, one of the plan's) and billing details (billingName, billingEmail, taxId, billingAddress from the address form, for tax invoices), checks the checkout's promotion code again, and answers a setup intent's client secret for Stripe's card fields (cards only). Each call is a card attempt: 429 past 5 on one checkout or 15 an hour; 410 once it has expired (an hour after it started).
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:write (when
view.ownerType === "org")
Path parameters
checkoutIdA checkout's id on the payment page (
chk_…).
Request body
interval"two-year" | "year" | "month"billingNamestring1–200 characters. Trimmed.
billingEmailstringUp to 254 characters. Email address.
taxIdstringUp to 40 characters. Trimmed.
billingAddressobjectbillingAddress.line1stringrequired1–200 characters. Trimmed.
billingAddress.line2stringUp to 200 characters. Trimmed.
billingAddress.citystringUp to 100 characters. Trimmed.
billingAddress.statestringUp to 100 characters. Trimmed.
billingAddress.postalCodestringUp to 20 characters. Trimmed.
billingAddress.countrystringrequiredMatches
^[A-Z]{2}$.
Errors
403Billing needs a signed-in person.404Checkout not found429Too many attempts. Try again in an hour.
curl -X POST 'https://api.cactive.com.au/v1/me/checkouts/{checkoutId}/start' \
-H "Authorization: Bearer $CACTIVE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"interval": "two-year",
"billingName": "Example",
"billingEmail": "person@example.com"
}'Response 200
{
checkout: {
checkoutId: string
kind: "card" | "invoice" | "subscribe"
status: "canceled" | "expired" | "failed" | "open" | "action" | "complete" | "processing"
app: string
ownerType: "user" | "org"
ownerId: string
ownerName?: string
currency: string
plan?: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}
interval?: "month" | "two-year" | "year"
intervals: ("month" | "two-year" | "year")[]
seats: number
unit?: number
amount?: number
gst?: number
trial?: {
days: number
endsAt: number
}
dueToday: number
invoice?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
account: {
billingName?: string
billingEmail?: string
taxId?: string
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
}
promotion?: {
code: string
discount: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
amount: number
discountedAmount: number
charges: number | "all"
nextCharge?: {
total: number
discount: number
tax?: number
}
dueToday: number
endsAt?: number
}
provider: {
name: string
mode: string
publishableKey?: string
}
returnUrl: string
cancelUrl: string
openUntil: number
outcome?: {
status?: string
invoiceId?: string
trialEndsAt?: number
message?: string
amount?: number
}
receipt?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
referenceRates?: {
base: "aud"
rates: {
usd: number
nzd: number
gbp: number
eur: number
}
asOf: string
}
guest?: boolean
email?: string
signup?: {
signupId: string
audience: "personal" | "business"
planId: string
planName?: string
next: "invite" | "done" | "account" | "pay" | "details" | "secure"
email?: string
orgName?: string
orgSlug?: string
orgId?: string
}
}
setup: {
setupIntentId: string
clientSecret: string
provider: string
mode: string
publishableKey?: string
}
}/ v1/ me/ checkouts/ :checkoutId/ code"Have a code?": checks a promotion code (code) for this checkout's plan, interval (the one shown; it becomes the checkout's) and seats and the buyer, prices it, and keeps it on the checkout, which redeems it when the subscription is made. Answers the checkout with promotion (the discount, each charge before and after, how many are discounted, what's due today). code: null takes it off. 400 says why a code can't be used; 429 past billing.promoChecksPerHour codes an hour.
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:write (when
view.ownerType === "org")
Path parameters
checkoutIdA checkout's id on the payment page (
chk_…).
Request body
codestringrequiredor null1–60 characters. Trimmed.
interval"two-year" | "year" | "month"
Errors
403Billing needs a signed-in person.404Checkout not found429Too many codes tried. Try again in an hour.
curl -X POST 'https://api.cactive.com.au/v1/me/checkouts/{checkoutId}/code' \
-H "Authorization: Bearer $CACTIVE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"code": "example"
}'Response 200
{
checkoutId: string
kind: "card" | "invoice" | "subscribe"
status: "canceled" | "expired" | "failed" | "open" | "action" | "complete" | "processing"
app: string
ownerType: "user" | "org"
ownerId: string
ownerName?: string
currency: string
plan?: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}
interval?: "month" | "two-year" | "year"
intervals: ("month" | "two-year" | "year")[]
seats: number
unit?: number
amount?: number
gst?: number
trial?: {
days: number
endsAt: number
}
dueToday: number
invoice?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
account: {
billingName?: string
billingEmail?: string
taxId?: string
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
}
promotion?: {
code: string
discount: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
amount: number
discountedAmount: number
charges: number | "all"
nextCharge?: {
total: number
discount: number
tax?: number
}
dueToday: number
endsAt?: number
}
provider: {
name: string
mode: string
publishableKey?: string
}
returnUrl: string
cancelUrl: string
openUntil: number
outcome?: {
status?: string
invoiceId?: string
trialEndsAt?: number
message?: string
amount?: number
}
receipt?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
referenceRates?: {
base: "aud"
rates: {
usd: number
nzd: number
gbp: number
eur: number
}
asOf: string
}
guest?: boolean
email?: string
signup?: {
signupId: string
audience: "personal" | "business"
planId: string
planName?: string
next: "invite" | "done" | "account" | "pay" | "details" | "secure"
email?: string
orgName?: string
orgSlug?: string
orgId?: string
}
}/ v1/ me/ checkouts/ :checkoutId/ completeWith the card confirmed (setupIntentId, the one start made): subscribes, replaces the card or pays the invoice. Answers the checkout (complete, or failed with the bank's message) and, when the bank wants the payment confirmed (3-D Secure), action.clientSecret for the browser; then confirm. An organization's checkout needs tenant:write there.
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:write (when
view.ownerType === "org")
Path parameters
checkoutIdA checkout's id on the payment page (
chk_…).
Request body
setupIntentIdstringrequiredMatches
^[A-Za-z0-9_]{3,255}$.
Errors
403Billing needs a signed-in person.404Checkout not found
curl -X POST 'https://api.cactive.com.au/v1/me/checkouts/{checkoutId}/complete' \
-H "Authorization: Bearer $CACTIVE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"setupIntentId": "<setupIntentId>"
}'Response 200
{
checkout: {
checkoutId: string
kind: "card" | "invoice" | "subscribe"
status: "canceled" | "expired" | "failed" | "open" | "action" | "complete" | "processing"
app: string
ownerType: "user" | "org"
ownerId: string
ownerName?: string
currency: string
plan?: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}
interval?: "month" | "two-year" | "year"
intervals: ("month" | "two-year" | "year")[]
seats: number
unit?: number
amount?: number
gst?: number
trial?: {
days: number
endsAt: number
}
dueToday: number
invoice?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
account: {
billingName?: string
billingEmail?: string
taxId?: string
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
}
promotion?: {
code: string
discount: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
amount: number
discountedAmount: number
charges: number | "all"
nextCharge?: {
total: number
discount: number
tax?: number
}
dueToday: number
endsAt?: number
}
provider: {
name: string
mode: string
publishableKey?: string
}
returnUrl: string
cancelUrl: string
openUntil: number
outcome?: {
status?: string
invoiceId?: string
trialEndsAt?: number
message?: string
amount?: number
}
receipt?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
referenceRates?: {
base: "aud"
rates: {
usd: number
nzd: number
gbp: number
eur: number
}
asOf: string
}
guest?: boolean
email?: string
signup?: {
signupId: string
audience: "personal" | "business"
planId: string
planName?: string
next: "invite" | "done" | "account" | "pay" | "details" | "secure"
email?: string
orgName?: string
orgSlug?: string
orgId?: string
}
}
action?: {
clientSecret: string
}
}/ v1/ me/ checkouts/ :checkoutId/ confirmAfter the bank's confirmation in the browser: the payment as the provider now has it, and the checkout complete or failed.
- Auth
- A person's token or an API key, as Authorization: Bearer.
- Scope
- tenant:write (when
view.ownerType === "org")
Path parameters
checkoutIdA checkout's id on the payment page (
chk_…).
Request body
localApprovalboolean
Errors
403Billing needs a signed-in person.404Checkout not found
curl -X POST 'https://api.cactive.com.au/v1/me/checkouts/{checkoutId}/confirm' \
-H "Authorization: Bearer $CACTIVE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"localApproval": true
}'Response 200
{
checkout: {
checkoutId: string
kind: "card" | "invoice" | "subscribe"
status: "canceled" | "expired" | "failed" | "open" | "action" | "complete" | "processing"
app: string
ownerType: "user" | "org"
ownerId: string
ownerName?: string
currency: string
plan?: {
planId: string
name: string
audience: "personal" | "business"
tagline?: string
priceMonthly?: number
priceAnnual?: number
priceTwoYear?: number
trialDays?: number
apps?: string[]
features?: string[]
support?: string
highlights: string[]
caityMessagesPerDay?: number
storageGb?: number
auditRetentionDays?: number
mailSendPerDay?: number
crmMaxRecords?: number
pipelineMinutes?: number
offered: boolean
isDefault: boolean
}
interval?: "month" | "two-year" | "year"
intervals: ("month" | "two-year" | "year")[]
seats: number
unit?: number
amount?: number
gst?: number
trial?: {
days: number
endsAt: number
}
dueToday: number
invoice?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
account: {
billingName?: string
billingEmail?: string
taxId?: string
card?: {
brand: string
last4: string
expMonth?: number
expYear?: number
}
billingAddress?: {
line1: string
line2?: string
city?: string
state?: string
postalCode?: string
country: string
}
}
promotion?: {
code: string
discount: {
percentOff?: number
amountOff?: number
currency?: string
duration: "once" | "repeating" | "forever"
durationInMonths?: number
code?: string
name?: string
startsAt?: number
endsAt?: number
}
amount: number
discountedAmount: number
charges: number | "all"
nextCharge?: {
total: number
discount: number
tax?: number
}
dueToday: number
endsAt?: number
}
provider: {
name: string
mode: string
publishableKey?: string
}
returnUrl: string
cancelUrl: string
openUntil: number
outcome?: {
status?: string
invoiceId?: string
trialEndsAt?: number
message?: string
amount?: number
}
receipt?: {
invoiceId: string
number?: string
status: "void" | "open" | "draft" | "paid" | "uncollectible"
currency: string
subtotal: number
discount?: number
tax: number
total: number
amountPaid: number
amountDue: number
periodStart?: number
periodEnd?: number
lines: {
description: string
quantity: number
amount: number
proration?: boolean
periodStart?: number
periodEnd?: number
}[]
issuedAt: number
paidAt?: number
hostedUrl?: string
pdfUrl?: string
billedTo?: string
billedEmail?: string
billedTaxId?: string
billedAddress?: string
supplier: {
name: string
abn: string
address: null | string
email: string
}
}
referenceRates?: {
base: "aud"
rates: {
usd: number
nzd: number
gbp: number
eur: number
}
asOf: string
}
guest?: boolean
email?: string
signup?: {
signupId: string
audience: "personal" | "business"
planId: string
planName?: string
next: "invite" | "done" | "account" | "pay" | "details" | "secure"
email?: string
orgName?: string
orgSlug?: string
orgId?: string
}
}
action?: {
clientSecret: string
}
}/ v1/ me/ checkouts/ :checkoutId/ cancelCloses a checkout that isn't complete and answers where to go back to (status=canceled).
- Auth
- A person's token or an API key, as Authorization: Bearer.
Path parameters
checkoutIdA checkout's id on the payment page (
chk_…).
Errors
403Billing needs a signed-in person.404Checkout not found
curl -X POST 'https://api.cactive.com.au/v1/me/checkouts/{checkoutId}/cancel' \
-H "Authorization: Bearer $CACTIVE_TOKEN"Response 200
{
returnUrl: string
}