Billing
Newest first. Unpaginated unless page is sent, in which case limit (default 25, max 250) applies and pagination is returned beside data; without page, limit is ignored and every invoice in scope is returned. A client-pinned credential sees only its own client's invoices; clientId and X-Client-Id are ignored for it.
Authorization
oauth2 billing:readOAuth2 client-credentials grant.
In: header
Scope: billing:read
Query Parameters
0 < value0 < value <= 250length <= 200Value in
- "ALL"
- "SENT"
- "UNSENT"
Header Parameters
Scope results to one client (brand). Resolve a client name to its id via GET /api/clients/lookup. Validated against the credential's tenant; ignored by a client-pinned credential.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/billing/invoices"{ "success": true, "data": [ { "id": "string", "tenantId": "string", "clientId": "string", "billingPeriodId": "string", "invoiceNumber": "string", "totalAmount": 0, "currency": "string", "generatedAt": "2019-08-24T14:15:22Z", "sentAt": "2019-08-24T14:15:22Z" } ], "pagination": { "page": 0, "limit": 0, "total": 0, "totalPages": 0 }}The invoice, with time-limited signed download URLs where object storage holds the rendered files. A client-pinned credential gets null URLs: use /download.
Authorization
oauth2 billing:readOAuth2 client-credentials grant.
In: header
Scope: billing:read
Path Parameters
Invoice id
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/billing/invoices/string"{ "success": true, "data": { "id": "string", "tenantId": "string", "clientId": "string", "billingPeriodId": "string", "invoiceNumber": "string", "totalAmount": 0, "currency": "string", "generatedAt": "2019-08-24T14:15:22Z", "sentAt": "2019-08-24T14:15:22Z", "csvSignedUrl": "string", "pdfSignedUrl": "string", "signedUrlsExpireAt": "2019-08-24T14:15:22Z" }}Fresh 7-day signed URLs for the stored CSV and PDF. Null for a client-pinned credential and when object storage is not configured; /download always works.
Authorization
oauth2 billing:readOAuth2 client-credentials grant.
In: header
Scope: billing:read
Path Parameters
Invoice id
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/billing/invoices/string/signed-urls"{ "success": true, "data": { "invoiceId": "string", "csvSignedUrl": "string", "pdfSignedUrl": "string", "expiresAt": "2019-08-24T14:15:22Z" }}Re-renders the invoice on demand and streams it as an attachment. A client-pinned credential receives the client projection: bin-storage lines read "Storage fee" and name no bin.
Authorization
oauth2 billing:readOAuth2 client-credentials grant.
In: header
Scope: billing:read
Path Parameters
Invoice id
Query Parameters
Value in
- "csv"
- "pdf"
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/billing/invoices/string/download?format=csv""string"Every charge in scope, newest occurrence first; filter by billingPeriodId to read one period's lines. A client-pinned credential sees the client view (the schema description lists the staff-only fields it does not receive).
Authorization
oauth2 billing:readOAuth2 client-credentials grant.
In: header
Scope: billing:read
Query Parameters
Value in
- "PICK"
- "LABEL"
- "RECEIVING_PALLET"
- "RECEIVING_CARTON"
- "STORAGE_PALLET"
- "STORAGE_BIN"
- "RETURN_PROCESSING"
- "AD_HOC"
- "SHIPPING_RECONCILIATION"
- "ORDER_FEES"
- "RECEIVING_FEES"
- "RETURN_FEES"
Value in
- "ACTIVE"
- "VOIDED"
Value in
- "SHIPMENT"
- "PACK_RECORD"
- "ORDER"
- "ORDER_LINE"
- "INBOUND_SHIPMENT"
- "PALLET"
- "BIN"
- "RETURN"
- "AD_HOC"
- "RECURRING"
- "MANUAL"
Header Parameters
Scope results to one client (brand). Resolve a client name to its id via GET /api/clients/lookup. Validated against the credential's tenant; ignored by a client-pinned credential.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/billing/charges"{ "success": true, "data": [ { "id": "string", "clientId": "string", "billingPeriodId": "string", "category": "PICK", "description": "string", "quantity": 0, "unitPrice": 0, "multiplier": 0, "amount": 0, "currency": "string", "status": "ACTIVE", "approvalStatus": "PENDING", "sourceType": "SHIPMENT", "sourceId": "string", "adHocChargeTypeId": "string", "occurredAt": "2019-08-24T14:15:22Z", "generatedAt": "2019-08-24T14:15:22Z", "orderNumber": "string" } ]}Signed amounts: a negative adjustment is a credit. A client-pinned credential sees the client view.
Authorization
oauth2 billing:readOAuth2 client-credentials grant.
In: header
Scope: billing:read
Query Parameters
Value in
- "PICK"
- "LABEL"
- "RECEIVING_PALLET"
- "RECEIVING_CARTON"
- "STORAGE_PALLET"
- "STORAGE_BIN"
- "RETURN_PROCESSING"
- "AD_HOC"
- "SHIPPING_RECONCILIATION"
- "ORDER_FEES"
- "RECEIVING_FEES"
- "RETURN_FEES"
Header Parameters
Scope results to one client (brand). Resolve a client name to its id via GET /api/clients/lookup. Validated against the credential's tenant; ignored by a client-pinned credential.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/billing/adjustments"{ "success": true, "data": [ { "id": "string", "clientId": "string", "billingPeriodId": "string", "chargeId": "string", "category": "PICK", "amount": 0, "description": "string", "appliesToType": "SHIPMENT", "appliesToId": "string", "origin": "MANUAL", "createdAt": "2019-08-24T14:15:22Z" } ]}Newest first, each with its running charges total. A period is OPEN while events accrue, then moves through CLOSING and FINALIZED to INVOICED.
Authorization
oauth2 billing:readOAuth2 client-credentials grant.
In: header
Scope: billing:read
Query Parameters
Value in
- "OPEN"
- "CLOSING"
- "FINALIZED"
- "INVOICED"
Header Parameters
Scope results to one client (brand). Resolve a client name to its id via GET /api/clients/lookup. Validated against the credential's tenant; ignored by a client-pinned credential.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/billing/periods"{ "success": true, "data": [ { "id": "string", "tenantId": "string", "clientId": "string", "startDate": "2019-08-24T14:15:22Z", "endDate": "2019-08-24T14:15:22Z", "status": "OPEN", "currency": "string", "finalizedAt": "2019-08-24T14:15:22Z", "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z", "chargesTotal": 0 } ]}Authorization
oauth2 billing:readOAuth2 client-credentials grant.
In: header
Scope: billing:read
Path Parameters
Billing period id
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/billing/periods/string"{ "success": true, "data": { "id": "string", "tenantId": "string", "clientId": "string", "startDate": "2019-08-24T14:15:22Z", "endDate": "2019-08-24T14:15:22Z", "status": "OPEN", "currency": "string", "finalizedAt": "2019-08-24T14:15:22Z", "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z", "chargesTotal": 0 }}Tenant-wide credentials only. A credential pinned to one client is refused (403), as that client's portal users are; use a tenant-wide credential with X-Client-Id. Drafts (isActive: false) are included; deleted cards are not.
Authorization
oauth2 rate-cards:readOAuth2 client-credentials grant.
In: header
Scope: rate-cards:read
Header Parameters
Scope results to one client (brand). Resolve a client name to its id via GET /api/clients/lookup. Validated against the credential's tenant; ignored by a client-pinned credential.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/billing/rate-cards"{ "success": true, "data": [ { "id": "string", "tenantId": "string", "clientId": "string", "name": "string", "effectiveFrom": "2019-08-24T14:15:22Z", "effectiveTo": "2019-08-24T14:15:22Z", "chargeShippingLabels": true, "isActive": true, "deletedAt": "2019-08-24T14:15:22Z", "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z" } ]}Tenant-wide credentials only. A credential pinned to one client is refused (403), as that client's portal users are; use a tenant-wide credential with X-Client-Id. Rules are ordered by category, then priority.
Authorization
oauth2 rate-cards:readOAuth2 client-credentials grant.
In: header
Scope: rate-cards:read
Path Parameters
Rate card id
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/billing/rate-cards/string"{ "success": true, "data": { "id": "string", "tenantId": "string", "clientId": "string", "name": "string", "effectiveFrom": "2019-08-24T14:15:22Z", "effectiveTo": "2019-08-24T14:15:22Z", "chargeShippingLabels": true, "isActive": true, "deletedAt": "2019-08-24T14:15:22Z", "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z", "rules": [ { "id": "string", "rateCardId": "string", "category": "PICK", "shape": "FLAT", "name": "string", "config": null, "selector": null, "selectorKey": "string", "priority": 0, "isActive": true, "sharedRuleId": "string", "deletedAt": "2019-08-24T14:15:22Z", "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z" } ] }}Tenant-wide credentials only. A credential pinned to one client is refused (403), as that client's portal users are; use a tenant-wide credential with X-Client-Id. The published cards that succeed one another without a gap, around the requested card.
Authorization
oauth2 rate-cards:readOAuth2 client-credentials grant.
In: header
Scope: rate-cards:read
Path Parameters
Rate card id
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/billing/rate-cards/string/versions"{ "success": true, "data": { "cardId": "string", "clientId": "string", "versions": [ { "id": "string", "name": "string", "effectiveFrom": "2019-08-24T14:15:22Z", "effectiveTo": "2019-08-24T14:15:22Z", "isCurrent": true, "isRequestedCard": true, "activeRuleCount": 0, "mintedByCorrection": true } ] }}Tenant-wide credentials only. A credential pinned to one client is refused (403), as that client's portal users are; use a tenant-wide credential with X-Client-Id. The last 100 edits to one rule, newest first, with the unit price before and after each.
Authorization
oauth2 rate-cards:readOAuth2 client-credentials grant.
In: header
Scope: rate-cards:read
Path Parameters
Rate card id
Rule id
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/billing/rate-cards/string/rules/string/history"{ "success": true, "data": [ { "id": "string", "action": "string", "sharedRuleId": "string", "performedByEmail": "string", "createdAt": "2019-08-24T14:15:22Z", "previousUnitPrice": 0, "newUnitPrice": 0, "previousValue": null, "newValue": null } ]}Tenant-wide credentials only. A credential pinned to one client is refused (403), as that client's portal users are; use a tenant-wide credential with X-Client-Id. category must be AD_HOC (any other category is 400). The charge lands in the client's OPEN period covering occurredAt (or the named OPEN billingPeriodId), else 409. amount = unitPrice × quantity (default 1, at most 1,000,000); money is a JSON number with at most two decimals, and amount must not exceed 9,999,999,999.99 (400 past either bound). Every API-posted charge lands PENDING on the Review Board whatever its charge type says, and bills only once a tenant admin approves it. Idempotency-Key is REQUIRED for API callers (400 without it). There is no edit: to correct a charge, void it and post again. The tenant's API access must list billing:write in its allowed scopes before a credential can hold it; no tenant has it by default.
Authorization
oauth2 billing:writeOAuth2 client-credentials grant.
In: header
Scope: billing:write
Header Parameters
Optional client-supplied key that makes this write safe to retry. A replay of a completed key returns the original response; an in-flight duplicate gets 409. A key is bound to the operation — method, URL and request body — and to the caller — the credential and its token scopes; reusing it with any of those changed gets 422.
length <= 255Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/api/billing/ad-hoc-charges" \ -H "Content-Type: application/json" \ -d '{ "clientId": "string", "category": "AD_HOC", "unitPrice": 0, "description": "string", "occurredAt": "2019-08-24T14:15:22Z" }'{ "success": true, "data": { "id": "string", "clientId": "string", "billingPeriodId": "string", "category": "PICK", "description": "string", "quantity": 0, "unitPrice": 0, "multiplier": 0, "amount": 0, "currency": "string", "status": "ACTIVE", "approvalStatus": "PENDING", "sourceType": "SHIPMENT", "sourceId": "string", "adHocChargeTypeId": "string", "occurredAt": "2019-08-24T14:15:22Z", "generatedAt": "2019-08-24T14:15:22Z" }}Tenant-wide credentials only. A credential pinned to one client is refused (403), as that client's portal users are; use a tenant-wide credential with X-Client-Id. A credential may void only the charges it posted itself; any other charge reads as 404. Refused (409) once the charge's period is no longer OPEN, or when the charge is already voided.
Authorization
oauth2 billing:writeOAuth2 client-credentials grant.
In: header
Scope: billing:write
Path Parameters
Charge id
Header Parameters
Optional client-supplied key that makes this write safe to retry. A replay of a completed key returns the original response; an in-flight duplicate gets 409. A key is bound to the operation — method, URL and request body — and to the caller — the credential and its token scopes; reusing it with any of those changed gets 422.
length <= 255Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/api/billing/charges/string/void" \ -H "Content-Type: application/json" \ -d '{ "reason": "string" }'{ "success": true, "data": { "id": "string", "clientId": "string", "billingPeriodId": "string", "category": "PICK", "description": "string", "quantity": 0, "unitPrice": 0, "multiplier": 0, "amount": 0, "currency": "string", "status": "ACTIVE", "approvalStatus": "PENDING", "sourceType": "SHIPMENT", "sourceId": "string", "adHocChargeTypeId": "string", "occurredAt": "2019-08-24T14:15:22Z", "generatedAt": "2019-08-24T14:15:22Z" }}