Lists the host's invoices, optionally filtered by status, recipient, or issue date. Sorted by issuedAt descending. Paginated.
AuthorizationRequiredBearer <token>API key as Bearer token
In: header
pageintegerPage number (0-based, default 0)
0Minimum: 0Maximum: 9007199254740991pageSizeintegerItems per page (default 20, max 100)
20Minimum: 1Maximum: 100statusstringFilter by status; omit to include all
"draft" | "open" | "payment_failed" | "paid" | "void"customerIdstringFilter by recipient contact id
subscriptionIdstringFilter to invoices generated by this subscription (renewals, proration adjustments)
issuedAfterstringOnly invoices issued on or after this date (ISO 8601)
"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"Format: "date-time"issuedBeforestringOnly invoices issued on or before this date (ISO 8601)
"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"Format: "date-time"fieldsstringComma-separated list of fields to return. Valid: id, hostId, customerId, customerEmail, customerFirstName, customerLastName, customerPhone, number, currency, subtotal, taxTotal, total, amountPaid, amountDue, status, autoCharge, issuedAt, dueAt, paidAt, voidedAt, subscriptionId, quoteId, createdAt, updatedAt. Omit for all fields.
curl -X GET "https://api.3common.com/v1/invoices/?status=draft&customerId=string&subscriptionId=string&issuedAfter=2019-08-24T14%3A15%3A22Z&issuedBefore=2019-08-24T14%3A15%3A22Z&fields=string" \
-H "Authorization: Bearer <token>"{
"data": [
{
"id": "string",
"hostId": "string",
"customerId": "string",
"customerEmail": "string",
"customerFirstName": "string",
"customerLastName": "string",
"customerPhone": "string",
"number": "string",
"currency": "USD",
"lineItems": [
{
"description": "string",
"quantity": 1,
"unitAmount": 9007199254740991,
"productId": "string",
"priceId": "string",
"eventId": "string",
"taxAmount": 9007199254740991,
"productType": "product",
"productName": "string",
"components": [
{
"productId": "string",
"productName": "string",
"productType": "product",
"productImageUrl": "string",
"eventId": "string",
"eventImageUrl": "string",
"eventName": "string",
"eventStart": "2019-08-24T14:15:22Z",
"eventEnd": "2019-08-24T14:15:22Z",
"eventLocation": "string",
"eventTimezone": "string",
"seatingInformation": {
"sectionId": "string",
"rowId": "string",
"seatId": "string",
"seatReferenceId": "string",
"sectionReferenceId": "string",
"priceLevelId": "string"
},
"disableQrCode": true,
"willCall": true
}
],
"disableQrCode": true,
"willCall": true,
"productImageUrl": "string",
"eventName": "string",
"eventImageUrl": "string",
"eventStart": "2019-08-24T14:15:22Z",
"eventEnd": "2019-08-24T14:15:22Z",
"eventLocation": "string",
"eventTimezone": "string",
"seatingInformation": {
"sectionId": "string",
"rowId": "string",
"seatId": "string",
"seatReferenceId": "string",
"sectionReferenceId": "string",
"priceLevelId": "string"
},
"inventoryConsumedAt": "2019-08-24T14:15:22Z"
}
],
"payments": [
{
"id": "string",
"status": "succeeded",
"amount": 9007199254740991,
"paidAt": "2019-08-24T14:15:22Z",
"idempotencyKey": "string",
"note": "string",
"externalId": "string",
"chargeId": "string",
"failureCode": "string",
"failureMessage": "string",
"refunds": [
{
"id": "string",
"amount": 9007199254740991,
"refundedAt": "2019-08-24T14:15:22Z",
"idempotencyKey": "string",
"reason": "string",
"note": "string",
"externalRefundId": "string",
"ledgerEntryId": "string"
}
]
}
],
"subtotal": -9007199254740991,
"taxTotal": -9007199254740991,
"total": -9007199254740991,
"amountPaid": -9007199254740991,
"amountDue": -9007199254740991,
"status": "draft",
"autoCharge": true,
"notes": "string",
"taxIds": [
{
"type": "string",
"value": "string"
}
],
"issuedAt": "2019-08-24T14:15:22Z",
"dueAt": "2019-08-24T14:15:22Z",
"paidAt": "2019-08-24T14:15:22Z",
"voidedAt": "2019-08-24T14:15:22Z",
"subscriptionId": "string",
"quoteId": "string",
"createdAt": "2019-08-24T14:15:22Z",
"updatedAt": "2019-08-24T14:15:22Z"
}
],
"hasMore": true
}export interface Response {
data: {
id?: string;
hostId?: string;
/**
* CRM contact id of the recipient
*/
customerId?: string;
/**
* Snapshot of the recipient's email captured at create time
*/
customerEmail?: string;
/**
* Snapshot of the recipient's first name captured at create time
*/
customerFirstName?: string;
/**
* Snapshot of the recipient's last name captured at create time
*/
customerLastName?: string;
/**
* Snapshot of the recipient's phone captured at create time
*/
customerPhone?: string;
/**
* Sequential invoice number; null while in draft
*/
number?: string | null;
currency?: "USD" | "CAD";
lineItems?: {
/**
* Human-readable description shown on the invoice
*/
description: string;
/**
* Whole units billed
*/
quantity: number;
/**
* Per-unit price in the invoice currency, minor units (cents for USD)
*/
unitAmount: number;
/**
* Optional reference to a Product in the catalog
*/
productId?: string;
/**
* Optional reference to the Price doc that backed this line (subscription billing)
*/
priceId?: string;
/**
* Optional reference to an Event when the underlying product was event-attached
*/
eventId?: string;
/**
* Optional tax for this line, minor units
*/
taxAmount?: number;
/**
* Snapshot of the product type at line-creation time; drives post-payment fulfillment
*/
productType?: "product" | "add-on" | "bundle" | "donation" | "event-ticket";
/**
* Snapshot of the product display name at line-creation time
*/
productName?: string;
/**
* Snapshot of the bundle's components, flat-expanded by qty. Set
* only when `productType === "bundle"`. Carries each component's
* product id + display name + image URL + (when applicable) event
* + seating snapshot so the fulfillment pipeline can issue
* information-equivalent component tickets and the tickets PDF
* can render the legacy "ticket"-style block per item.
*/
components?: {
productId: string;
productName: string;
/**
* Catalog product type for the component — drives sort + visual treatment in the rendered bundle items list.
*/
productType?: "product" | "add-on" | "bundle" | "donation" | "event-ticket";
productImageUrl?: string;
/**
* Per-component parent event id — snapshotted onto the issued component ticket as legacy `event_id` so b2c availability and seat-occupation queries see the sale.
*/
eventId?: string;
/**
* Component event hero image — fallback artwork for the pulled-out ticket card when the component product has no image.
*/
eventImageUrl?: string;
eventName?: string;
/**
* ISO 8601 start datetime for the component's event/timeslot.
*/
eventStart?: string;
eventEnd?: string;
eventLocation?: string;
/**
* IANA timezone identifier for the component event — drives printed-date localization on the pulled-out ticket.
*/
eventTimezone?: string;
/**
* Slim venue seating assignment. The display labels (sectionId,
* rowId, seatId) are what the printed ticket shows; the reference
* ids are preserved for compatibility with the legacy seat-chart
* system.
*/
seatingInformation?: {
/**
* Section display label (e.g. "A").
*/
sectionId?: string;
/**
* Row display label (e.g. "5").
*/
rowId?: string;
/**
* Seat display label (e.g. "12").
*/
seatId?: string;
seatReferenceId?: string;
sectionReferenceId?: string;
priceLevelId?: string;
};
/**
* Component product's own disable_qr_code — the issued component ticket skips its QR (printable stub only).
*/
disableQrCode?: boolean;
/**
* Component product's own will_call — the issued component ticket uses will call fulfillment (no stub, collected at the venue).
*/
willCall?: boolean;
}[];
/**
* Snapshot of the underlying `Product.disable_qr_code` flag.
* When true, the issued ticket renders a "No scan" badge on the PDF
* and skips QR generation. Donations are scannable by default unless
* the host opts the product out via this flag.
*/
disableQrCode?: boolean;
/**
* Snapshot of the underlying `Product.will_call` flag. When true,
* the issued ticket uses will call fulfillment: no PDF stub is
* rendered, the ticket is not scannable, and the customer collects
* it at the venue. Independent of `disableQrCode`.
*/
willCall?: boolean;
/**
* Snapshot of the underlying `Product.image` URL — rendered as
* the ticket-stub artwork on the issued PDF. Absent products fall
* back to the event image (when set), then to a typographic
* placeholder.
*/
productImageUrl?: string;
/**
* Snapshot of the parent event's display name when the line was event-attached.
*/
eventName?: string;
/**
* Snapshot of the parent event's hero image URL — the renderer
* uses it as the ticket-stub artwork fallback when the product
* itself has no image.
*/
eventImageUrl?: string;
/**
* ISO 8601 start datetime for the parent event (or per-occurrence timeslot).
*/
eventStart?: string;
/**
* ISO 8601 end datetime for the parent event.
*/
eventEnd?: string;
/**
* Pre-formatted location label snapshotted at line creation.
*/
eventLocation?: string;
/**
* IANA timezone identifier for the parent event (e.g.
* `America/Los_Angeles`). Drives printed-date localization
* so the holder sees the event-local time + TZ abbreviation.
*/
eventTimezone?: string;
/**
* Per-line venue seating assignment. Mirrors the legacy
* `seatingInformation` field on a ticket so the new tickets
* PDF prints the same seat info the legacy PDF did.
*/
seatingInformation?: {
/**
* Section display label (e.g. "A").
*/
sectionId?: string;
/**
* Row display label (e.g. "5").
*/
rowId?: string;
/**
* Seat display label (e.g. "12").
*/
seatId?: string;
seatReferenceId?: string;
sectionReferenceId?: string;
priceLevelId?: string;
};
/**
* Stamped by the fulfillment pipeline once
* `InventoryRepository.consume()` has succeeded for this
* line. Drives per-line consume idempotency: a replayed
* fulfillment skips already-stamped lines and runs consume
* on unstamped ones, so a partial-failure state (tickets
* persisted but consume threw) recovers without
* double-decrementing inventory.
*/
inventoryConsumedAt?: string;
}[];
/**
* Audit log of every payment applied to this invoice
*/
payments?: {
id: string;
/**
* Outcome of this payment attempt.
* - succeeded: money was captured. Counts toward the parent invoice's
* `amountPaid` total.
* - failed: an auto-charge attempt was rejected (decline / SCA / no
* card). Kept on the audit log for visibility; does NOT count
* toward `amountPaid`.
*/
status: "succeeded" | "failed";
/**
* Amount applied, minor units
*/
amount: number;
paidAt: string;
/**
* Caller-supplied dedupe key, if one was provided
*/
idempotencyKey?: string;
/**
* Free-form note (payment method, upstream provider id, etc.)
*/
note?: string;
/**
* Stripe PaymentIntent id (`pi_…`) for Stripe-Connect payments
*/
externalId?: string;
/**
* Stripe Charge id (`ch_…`); refund operations key off this
*/
chargeId?: string;
/**
* Stripe error code on a failed attempt (e.g. `card_declined`, `authentication_required`)
*/
failureCode?: string;
/**
* Stripe customer-facing decline message on a failed attempt
*/
failureMessage?: string;
/**
* Refunds applied against this payment. Cumulative refunds are
* capped at `amount`; the host's true net = amount - sum(refunds).
*/
refunds?: {
id: string;
/**
* Refund amount, minor units of the parent invoice currency
*/
amount: number;
refundedAt: string;
idempotencyKey?: string;
/**
* Stripe reason: duplicate | fraudulent | requested_by_customer
*/
reason?: string;
/**
* Free-form host note (internal, not shown to customer)
*/
note?: string;
/**
* Stripe Refund id (`re_…`) for ops lookups
*/
externalRefundId?: string;
/**
* Pointer to the matching Ledger row that drives payouts
*/
ledgerEntryId?: string;
}[];
}[];
/**
* Sum of (qty * unitAmount), minor units
*/
subtotal?: number;
/**
* Sum of line taxAmount, minor units
*/
taxTotal?: number;
/**
* subtotal + taxTotal, minor units
*/
total?: number;
/**
* Sum of payments received, minor units
*/
amountPaid?: number;
/**
* total - amountPaid, clamped to >= 0
*/
amountDue?: number;
/**
* Invoice lifecycle status.
* - draft: not yet issued; freely editable
* - open: finalized and issued; awaiting payment
* - payment_failed: an off-session auto-charge attempt was rejected
* (decline / SCA / no card). The invoice is still owed; the host
* can retry the charge or the customer can pay manually.
* - paid: fully paid
* - void: cancelled before payment
*/
status?: "draft" | "open" | "payment_failed" | "paid" | "void";
/**
* When true, finalize attempts to off-session charge the customer's
* saved card immediately. On charge success the invoice transitions
* straight to `paid`; on failure to `payment_failed`. Default
* false — host has to opt in.
*/
autoCharge?: boolean;
notes?: string;
/**
* Snapshot of the host's registered tax-IDs at the time the invoice
* was issued. Rendered alongside the host's company info on the PDF
* and email body. Optional/empty when the host hasn't recorded any.
*/
taxIds?: {
/**
* Internal type code for the tax-ID (e.g. 'us_ein', 'ca_gst_hst', 'eu_vat').
* Display labels are derived at render time so the persisted invoice
* doesn't bake in a label that might be reworded.
*/
type: string;
/**
* The tax-ID number as the host has it registered
*/
value: string;
}[];
issuedAt?: string;
dueAt?: string;
paidAt?: string;
voidedAt?: string;
/**
* Set when generated by a billing Subscription
*/
subscriptionId?: string;
/**
* Set when accepted from a Quote
*/
quoteId?: string;
createdAt?: string;
updatedAt?: string;
}[];
hasMore: boolean;
}
Renew Subscription
Advances a subscription to its next billing period and generates an invoice. If cancelAtPeriodEnd was set, transitions to canceled instead. The Phase 4 scheduler will call this on cycle.
Create Invoice
Creates a new draft invoice. Totals are computed from line items. The invoice must be finalized before it is issued to the customer.