Recompose an invoice
Composes an invoice again from the usage journal as it is now, keeping its BASE lines as they were sold. A held DRAFT is rewritten in place (200), under the subscription's current provider and terms: issued when its journal is now sound and its provider takes as many items, held again otherwise. A VOID invoice gets a replacement for the same boundary (201), under the subscription's current terms and billing e-mail. Any other invoice must be voided first. Requires billing to be enabled for the organization.
Authorization
bearerAuth write:billingA JWT verified by the proxy in front of this API, or a Kaiten access token (ksh_...) — send either as Authorization: Bearer <token>. The scopes listed on each operation are checked server-side against current stored user assignments or stored service-token permissions, never JWT claims; write:<module> implies read:<module>, and read:* / write:* are wildcards over every module. x-kaiten-scopes lists every scope such a token can carry, including those enforced by a service in front of this API rather than by one of its operations.
In: header
Scope: write:billing
Path Parameters
Invoice identifier
Response Body
application/json
application/json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
application/problem+json
curl -X POST "https://app.kaiten.sh/api/invoices/string/recompose"{
"billingEmail": "string",
"boundaryAt": "2019-08-24T14:15:22Z",
"collectionMethod": "SEND_INVOICE",
"createdAt": "2019-08-24T14:15:22Z",
"currency": "EUR",
"customerName": "string",
"customerSlug": "string",
"daysUntilDue": 0,
"discountTotal": 0,
"dueAt": "2019-08-24T14:15:22Z",
"handoff": {
"acknowledgedAt": "2019-08-24T14:15:22Z",
"claimCount": 0,
"externalReference": "string",
"leaseId": "string",
"leasedUntil": "2019-08-24T14:15:22Z",
"status": "NOT_REQUIRED"
},
"handoffStatus": "NOT_REQUIRED",
"hold": {
"heldAt": "2019-08-24T14:15:22Z",
"releaseReason": "string",
"releasedAt": "2019-08-24T14:15:22Z",
"releasedBy": "string"
},
"holdDetail": {
"itemLimit": {
"items": 0,
"limit": 0,
"providerKind": "STRIPE"
},
"pairs": [
{
"counterReportSeq": 0,
"detail": "string",
"entitlementId": "string",
"expected": "string",
"firstSeq": 0,
"found": "string",
"instanceId": "string",
"invariant": "string",
"lastSeq": 0,
"reportSeq": 0
}
]
},
"holdReason": "LEDGER_SEQUENCE_GAP",
"id": "string",
"instanceName": "string",
"instanceSlug": "string",
"issuedAt": "2019-08-24T14:15:22Z",
"kind": "ACTIVATION",
"licenseId": "string",
"licenseSlug": "string",
"lines": [
{
"addonId": "string",
"addonPriceId": "string",
"amount": 2440,
"billingModel": "FLAT_FEE",
"billingTiming": "ADVANCE",
"capped": true,
"description": "3.05 × 8.00 EUR (per 10k tokens); 130,500 used; 30,500 above the applied limit (100,000)",
"discount": {
"allocations": [
{
"amount": 0,
"targetSeq": 0
}
],
"application": 0,
"applicationsMax": 0,
"appliesTo": "LICENSE_BASE",
"base": "string",
"currency": "string",
"discountType": "PERCENTAGE",
"discountValue": "string",
"targetSeqs": [
0
]
},
"entitlementId": "string",
"entitlementSlug": "string",
"id": "string",
"instanceAddonId": "string",
"instanceVoucherId": "string",
"label": "Tokens — overage",
"licensePriceId": "string",
"metering": {
"ledger": {
"firstSeq": 0,
"instanceId": "string",
"lastSeq": 0,
"rows": 0,
"sumDelta": "string",
"sumOverage": "string"
},
"measuredQuantity": "30500",
"negativeSegmentsFloored": 0,
"saleUnitFactor": "10000",
"windows": 1
},
"overage": {
"limits": [
{
"limitValue": "100000",
"overagePercent": 50,
"rows": 0
}
],
"overageMeasured": "30500",
"usageMeasured": "130500"
},
"provider": {
"amount": 0,
"couponIds": [
"string"
],
"externalLineId": "string"
},
"quantity": "3.05",
"seq": 0,
"serviceFrom": "2019-08-24T14:15:22Z",
"serviceTo": "2019-08-24T14:15:22Z",
"trueUp": {
"billedQuantity": 0,
"maxQuantity": 0
},
"type": "BASE",
"unitAmountDecimal": "800",
"voucherId": "string"
}
],
"overdue": true,
"paidAt": "2019-08-24T14:15:22Z",
"provider": {
"externalCustomerId": "string",
"externalInvoiceId": "string",
"hostedInvoiceUrl": "string",
"invoiceNumber": "string",
"invoicePdfUrl": "string",
"lastPaymentError": "string",
"lastPushError": "string",
"nextPushAt": "2019-08-24T14:15:22Z",
"pushAttempts": 0,
"pushedAt": "2019-08-24T14:15:22Z",
"reconciledAt": "2019-08-24T14:15:22Z",
"reconciliationDetail": {
"discounts": [
{
"couponId": "string",
"kaitenAmount": 0,
"lineId": "string",
"providerAmount": 0,
"seq": 0,
"targetSeq": 0
}
],
"dueDate": {
"kaitenDueAt": "2019-08-24T14:15:22Z",
"providerDueAt": "2019-08-24T14:15:22Z"
},
"extraDiscounts": [
{
"amount": 0,
"discountId": "string",
"externalLineId": "string"
}
],
"extraInProvider": [
"string"
],
"inclusiveTax": true,
"lines": [
{
"externalLineId": "string",
"kaitenAmount": 0,
"lineId": "string",
"providerAmount": 0,
"seq": 0
}
],
"missingInProvider": [
"string"
],
"totals": {
"kaitenTotal": 0,
"providerSubtotal": 0,
"providerTotalDiscount": 0,
"providerTotalExcludingTax": 0
},
"warnings": [
"string"
]
},
"reconciliationStatus": "MATCHED",
"status": "draft",
"syncedAt": "2019-08-24T14:15:22Z",
"totalExcludingTax": 0
},
"providerKind": "NOOP",
"replacedByInvoiceId": "string",
"replacesInvoiceId": "string",
"serviceFrom": "2019-08-24T14:15:22Z",
"serviceTo": "2019-08-24T14:15:22Z",
"status": "DRAFT",
"subtotal": 0,
"total": 0,
"uncollectibleAt": "2019-08-24T14:15:22Z",
"updatedAt": "2019-08-24T14:15:22Z",
"voidReason": "string",
"voidedAt": "2019-08-24T14:15:22Z"
}{
"billingEmail": "string",
"boundaryAt": "2019-08-24T14:15:22Z",
"collectionMethod": "SEND_INVOICE",
"createdAt": "2019-08-24T14:15:22Z",
"currency": "EUR",
"customerName": "string",
"customerSlug": "string",
"daysUntilDue": 0,
"discountTotal": 0,
"dueAt": "2019-08-24T14:15:22Z",
"handoff": {
"acknowledgedAt": "2019-08-24T14:15:22Z",
"claimCount": 0,
"externalReference": "string",
"leaseId": "string",
"leasedUntil": "2019-08-24T14:15:22Z",
"status": "NOT_REQUIRED"
},
"handoffStatus": "NOT_REQUIRED",
"hold": {
"heldAt": "2019-08-24T14:15:22Z",
"releaseReason": "string",
"releasedAt": "2019-08-24T14:15:22Z",
"releasedBy": "string"
},
"holdDetail": {
"itemLimit": {
"items": 0,
"limit": 0,
"providerKind": "STRIPE"
},
"pairs": [
{
"counterReportSeq": 0,
"detail": "string",
"entitlementId": "string",
"expected": "string",
"firstSeq": 0,
"found": "string",
"instanceId": "string",
"invariant": "string",
"lastSeq": 0,
"reportSeq": 0
}
]
},
"holdReason": "LEDGER_SEQUENCE_GAP",
"id": "string",
"instanceName": "string",
"instanceSlug": "string",
"issuedAt": "2019-08-24T14:15:22Z",
"kind": "ACTIVATION",
"licenseId": "string",
"licenseSlug": "string",
"lines": [
{
"addonId": "string",
"addonPriceId": "string",
"amount": 2440,
"billingModel": "FLAT_FEE",
"billingTiming": "ADVANCE",
"capped": true,
"description": "3.05 × 8.00 EUR (per 10k tokens); 130,500 used; 30,500 above the applied limit (100,000)",
"discount": {
"allocations": [
{
"amount": 0,
"targetSeq": 0
}
],
"application": 0,
"applicationsMax": 0,
"appliesTo": "LICENSE_BASE",
"base": "string",
"currency": "string",
"discountType": "PERCENTAGE",
"discountValue": "string",
"targetSeqs": [
0
]
},
"entitlementId": "string",
"entitlementSlug": "string",
"id": "string",
"instanceAddonId": "string",
"instanceVoucherId": "string",
"label": "Tokens — overage",
"licensePriceId": "string",
"metering": {
"ledger": {
"firstSeq": 0,
"instanceId": "string",
"lastSeq": 0,
"rows": 0,
"sumDelta": "string",
"sumOverage": "string"
},
"measuredQuantity": "30500",
"negativeSegmentsFloored": 0,
"saleUnitFactor": "10000",
"windows": 1
},
"overage": {
"limits": [
{
"limitValue": "100000",
"overagePercent": 50,
"rows": 0
}
],
"overageMeasured": "30500",
"usageMeasured": "130500"
},
"provider": {
"amount": 0,
"couponIds": [
"string"
],
"externalLineId": "string"
},
"quantity": "3.05",
"seq": 0,
"serviceFrom": "2019-08-24T14:15:22Z",
"serviceTo": "2019-08-24T14:15:22Z",
"trueUp": {
"billedQuantity": 0,
"maxQuantity": 0
},
"type": "BASE",
"unitAmountDecimal": "800",
"voucherId": "string"
}
],
"overdue": true,
"paidAt": "2019-08-24T14:15:22Z",
"provider": {
"externalCustomerId": "string",
"externalInvoiceId": "string",
"hostedInvoiceUrl": "string",
"invoiceNumber": "string",
"invoicePdfUrl": "string",
"lastPaymentError": "string",
"lastPushError": "string",
"nextPushAt": "2019-08-24T14:15:22Z",
"pushAttempts": 0,
"pushedAt": "2019-08-24T14:15:22Z",
"reconciledAt": "2019-08-24T14:15:22Z",
"reconciliationDetail": {
"discounts": [
{
"couponId": "string",
"kaitenAmount": 0,
"lineId": "string",
"providerAmount": 0,
"seq": 0,
"targetSeq": 0
}
],
"dueDate": {
"kaitenDueAt": "2019-08-24T14:15:22Z",
"providerDueAt": "2019-08-24T14:15:22Z"
},
"extraDiscounts": [
{
"amount": 0,
"discountId": "string",
"externalLineId": "string"
}
],
"extraInProvider": [
"string"
],
"inclusiveTax": true,
"lines": [
{
"externalLineId": "string",
"kaitenAmount": 0,
"lineId": "string",
"providerAmount": 0,
"seq": 0
}
],
"missingInProvider": [
"string"
],
"totals": {
"kaitenTotal": 0,
"providerSubtotal": 0,
"providerTotalDiscount": 0,
"providerTotalExcludingTax": 0
},
"warnings": [
"string"
]
},
"reconciliationStatus": "MATCHED",
"status": "draft",
"syncedAt": "2019-08-24T14:15:22Z",
"totalExcludingTax": 0
},
"providerKind": "NOOP",
"replacedByInvoiceId": "string",
"replacesInvoiceId": "string",
"serviceFrom": "2019-08-24T14:15:22Z",
"serviceTo": "2019-08-24T14:15:22Z",
"status": "DRAFT",
"subtotal": 0,
"total": 0,
"uncollectibleAt": "2019-08-24T14:15:22Z",
"updatedAt": "2019-08-24T14:15:22Z",
"voidReason": "string",
"voidedAt": "2019-08-24T14:15:22Z"
}{
"code": "License.NotFound",
"detail": "license not found",
"errorId": "3f6b1a2c-7c1e-4d0b-9d5f-2b0a1c4e8d31",
"errors": [
{
"location": "string",
"message": "string",
"value": null
}
],
"instance": "/api/licenses/enterprise",
"status": 404,
"title": "Not Found",
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.4"
}{
"code": "License.NotFound",
"detail": "license not found",
"errorId": "3f6b1a2c-7c1e-4d0b-9d5f-2b0a1c4e8d31",
"errors": [
{
"location": "string",
"message": "string",
"value": null
}
],
"instance": "/api/licenses/enterprise",
"status": 404,
"title": "Not Found",
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.4"
}{
"code": "License.NotFound",
"detail": "license not found",
"errorId": "3f6b1a2c-7c1e-4d0b-9d5f-2b0a1c4e8d31",
"errors": [
{
"location": "string",
"message": "string",
"value": null
}
],
"instance": "/api/licenses/enterprise",
"status": 404,
"title": "Not Found",
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.4"
}{
"code": "License.NotFound",
"detail": "license not found",
"errorId": "3f6b1a2c-7c1e-4d0b-9d5f-2b0a1c4e8d31",
"errors": [
{
"location": "string",
"message": "string",
"value": null
}
],
"instance": "/api/licenses/enterprise",
"status": 404,
"title": "Not Found",
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.4"
}{
"code": "License.NotFound",
"detail": "license not found",
"errorId": "3f6b1a2c-7c1e-4d0b-9d5f-2b0a1c4e8d31",
"errors": [
{
"location": "string",
"message": "string",
"value": null
}
],
"instance": "/api/licenses/enterprise",
"status": 404,
"title": "Not Found",
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.4"
}{
"code": "License.NotFound",
"detail": "license not found",
"errorId": "3f6b1a2c-7c1e-4d0b-9d5f-2b0a1c4e8d31",
"errors": [
{
"location": "string",
"message": "string",
"value": null
}
],
"instance": "/api/licenses/enterprise",
"status": 404,
"title": "Not Found",
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.4"
}{
"code": "License.NotFound",
"detail": "license not found",
"errorId": "3f6b1a2c-7c1e-4d0b-9d5f-2b0a1c4e8d31",
"errors": [
{
"location": "string",
"message": "string",
"value": null
}
],
"instance": "/api/licenses/enterprise",
"status": 404,
"title": "Not Found",
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.4"
}Mark an invoice paid
Records that a MANUAL invoice was paid. An invoice still waiting in the handoff queue is acknowledged by the same write. Marking it paid again with the same external reference answers it unchanged. An invoice a payment provider collects is settled there. Requires billing to be enabled for the organization.
Release a held invoice
Accepts a held invoice as composed and issues it: MANUAL and pending in the handoff queue, or PAID when nothing is owed. The release keeps who released it and why. 409 .ProviderItemLimit for a PROVIDER_ITEM_LIMIT hold, which its provider would refuse: switch the subscription to NoOp and recompose in place, or void and recompose after that switch. Requires billing to be enabled for the organization.