API reference
Rent-to-Own Agreement API
Inspect installment agreements and cancel an owned agreement without initiating a new charge.
Read the agreement, not only the payment count
Developer list and detail calls use orders.view and all-products workspace scope. The customer detail route resolves ownership from the signed-in account. Do not reuse a developer token for a customer action or expose another customer agreement.
The list supports productId, status and limit, with a default of 50 and a maximum of 200. Detail includes installment history. List results do not load every installment; an empty list-level installments array is not proof that no payments exist.
Amounts and access remain separate
Amounts with Cents suffixes are integer minor units in the returned currency. Compare paid and net-paid installment counts with refunded/disputed amounts, ownershipState, accessState and ownedAt. A scheduled date is not a captured payment, and a browser success page is not earned ownership.
Reading an agreement does not authorize a collection or an administrative adjustment. Live rent-to-own installment checkout remains unavailable. This is separate from supported keep_products subscription bundles; no new payment method, payout behavior or production installment availability is implied.
Buyer identity is not contact ownership
A saved customer_user_id must match the signed-in account, even if the contact email matches another account. An unbound legacy agreement may use the current verified account email. Owning an imported contact as a developer does not make you the buyer. Customer list, detail and cancellation use the same ownership boundary; a foreign agreement returns 404.
Cancel the agreement named in the route
POST the cancellation to /api/rent-to-own/customer/agreements/{agreementId}/cancel. Only reason is customer-editable. The route identifies the agreement and the account session identifies the buyer; do not send buyerUser, userId, another agreementId or a cancellation policy override.
The saved agreement policy determines immediate locking or period-end cancellation. Repeated requests preserve the existing local cancellation with unchanged:true. A recorded provider confirmation is not sent again; an unfinished provider step can be retried with the same provider idempotency key. Completed/owned, refunded, disputed, revoked or ownership-revoked agreements cannot be changed here. Period-end cancellation preserves pending, past-due, grace and suspended lifecycle states so that existing expiry and access checks still run. Cancellation never upgrades them into paid access.
A payment-provider failure returns 502 with code rent_to_own_cancellation_pending, retryable:true and localCancellationSaved:true. The local access decision remains saved; metadata.providerCancellation.status stays pending until provider confirmation is recorded. Retry the same cancellation request after a temporary failure, not a checkout or charge. Do not treat pending as confirmed cancellation. No automatic retry schedule is promised; unresolved provider failures require support reconciliation.
SoundSync
Lifecycle and payment contracts
SoundSync
Requests and responses
/api/developer/rent-to-own/agreements
List developer rent-to-own agreements
- Auth
- Account Bearer JWT
- Scope
- orders.view and all-products workspace scope.
- Request fields
- query productId: integer
- query status: string
- query limit: integer
- Returns
- HTTP 200: agreements.
Request, response and error reference
Query and header parameters
[
{
"name": "productId",
"in": "query",
"schema": {
"type": "integer",
"minimum": 1
},
"required": false,
"description": ""
},
{
"name": "status",
"in": "query",
"schema": {
"type": "string"
},
"required": false,
"description": ""
},
{
"name": "limit",
"in": "query",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
},
"required": false,
"description": ""
}
]
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"agreements": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"developerId": {
"type": "integer",
"minimum": 1
},
"customerUserId": {
"type": [
"integer",
"null"
]
},
"customerId": {
"type": "integer",
"minimum": 1
},
"productId": {
"type": "integer",
"minimum": 1
},
"productName": {
"type": [
"string",
"null"
]
},
"planVersionId": {
"type": "integer",
"minimum": 1
},
"checkoutId": {
"type": [
"integer",
"null"
]
},
"entitlementId": {
"type": [
"integer",
"null"
]
},
"provider": {
"type": "string"
},
"providerSubscriptionId": {
"type": [
"string",
"null"
]
},
"environment": {
"type": "string"
},
"status": {
"type": "string"
},
"accessState": {
"type": "string"
},
"ownershipState": {
"type": "string"
},
"currency": {
"type": "string"
},
"cashPriceCents": {
"type": "integer"
},
"installmentAmountCents": {
"type": "integer"
},
"installmentCount": {
"type": "integer"
},
"totalContractCents": {
"type": "integer"
},
"paidInstallmentCount": {
"type": "integer"
},
"netPaidInstallmentCount": {
"type": "integer"
},
"paidAmountCents": {
"type": "integer"
},
"refundedAmountCents": {
"type": "integer"
},
"disputedAmountCents": {
"type": "integer"
},
"currentPeriodStart": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"currentPeriodEnd": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"nextPaymentAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"failedPaymentGraceUntil": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"cancelAtPeriodEnd": {
"type": "boolean"
},
"canceledAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"completedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"ownedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"revokedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"installments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"installmentNumber": {
"type": "integer"
},
"status": {
"type": "string"
},
"currency": {
"type": "string"
},
"amountDueCents": {
"type": "integer"
},
"amountPaidCents": {
"type": "integer"
},
"amountRefundedCents": {
"type": "integer"
},
"taxAmountCents": {
"type": "integer"
},
"discountAmountCents": {
"type": "integer"
},
"paidAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"refundedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"disputedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"orderId": {
"type": [
"integer",
"null"
]
}
},
"additionalProperties": true
}
},
"metadata": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/developer/rent-to-own/agreements/{agreementId}
Read a developer agreement and installment history
- Auth
- Account Bearer JWT
- Scope
- orders.view and all-products workspace scope; developer ownership is checked.
- Returns
- HTTP 200: agreement.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"agreement": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"developerId": {
"type": "integer",
"minimum": 1
},
"customerUserId": {
"type": [
"integer",
"null"
]
},
"customerId": {
"type": "integer",
"minimum": 1
},
"productId": {
"type": "integer",
"minimum": 1
},
"productName": {
"type": [
"string",
"null"
]
},
"planVersionId": {
"type": "integer",
"minimum": 1
},
"checkoutId": {
"type": [
"integer",
"null"
]
},
"entitlementId": {
"type": [
"integer",
"null"
]
},
"provider": {
"type": "string"
},
"providerSubscriptionId": {
"type": [
"string",
"null"
]
},
"environment": {
"type": "string"
},
"status": {
"type": "string"
},
"accessState": {
"type": "string"
},
"ownershipState": {
"type": "string"
},
"currency": {
"type": "string"
},
"cashPriceCents": {
"type": "integer"
},
"installmentAmountCents": {
"type": "integer"
},
"installmentCount": {
"type": "integer"
},
"totalContractCents": {
"type": "integer"
},
"paidInstallmentCount": {
"type": "integer"
},
"netPaidInstallmentCount": {
"type": "integer"
},
"paidAmountCents": {
"type": "integer"
},
"refundedAmountCents": {
"type": "integer"
},
"disputedAmountCents": {
"type": "integer"
},
"currentPeriodStart": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"currentPeriodEnd": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"nextPaymentAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"failedPaymentGraceUntil": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"cancelAtPeriodEnd": {
"type": "boolean"
},
"canceledAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"completedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"ownedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"revokedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"installments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"installmentNumber": {
"type": "integer"
},
"status": {
"type": "string"
},
"currency": {
"type": "string"
},
"amountDueCents": {
"type": "integer"
},
"amountPaidCents": {
"type": "integer"
},
"amountRefundedCents": {
"type": "integer"
},
"taxAmountCents": {
"type": "integer"
},
"discountAmountCents": {
"type": "integer"
},
"paidAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"refundedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"disputedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"orderId": {
"type": [
"integer",
"null"
]
}
},
"additionalProperties": true
}
},
"metadata": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/rent-to-own/customer/agreements/{agreementId}
Read an agreement owned by the signed-in customer
- Auth
- Account Bearer JWT
- Scope
- Signed-in customer account. A saved customer_user_id must match; only unbound legacy agreements can use the current verified account email.
- Returns
- HTTP 200: agreement.
- Notes
- Imported-contact ownership does not grant buyer access. A visible agreement is not authorization to charge again or alter its installment count.
Request, response and error reference
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"agreement": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"developerId": {
"type": "integer",
"minimum": 1
},
"customerUserId": {
"type": [
"integer",
"null"
]
},
"customerId": {
"type": "integer",
"minimum": 1
},
"productId": {
"type": "integer",
"minimum": 1
},
"productName": {
"type": [
"string",
"null"
]
},
"planVersionId": {
"type": "integer",
"minimum": 1
},
"checkoutId": {
"type": [
"integer",
"null"
]
},
"entitlementId": {
"type": [
"integer",
"null"
]
},
"provider": {
"type": "string"
},
"providerSubscriptionId": {
"type": [
"string",
"null"
]
},
"environment": {
"type": "string"
},
"status": {
"type": "string"
},
"accessState": {
"type": "string"
},
"ownershipState": {
"type": "string"
},
"currency": {
"type": "string"
},
"cashPriceCents": {
"type": "integer"
},
"installmentAmountCents": {
"type": "integer"
},
"installmentCount": {
"type": "integer"
},
"totalContractCents": {
"type": "integer"
},
"paidInstallmentCount": {
"type": "integer"
},
"netPaidInstallmentCount": {
"type": "integer"
},
"paidAmountCents": {
"type": "integer"
},
"refundedAmountCents": {
"type": "integer"
},
"disputedAmountCents": {
"type": "integer"
},
"currentPeriodStart": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"currentPeriodEnd": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"nextPaymentAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"failedPaymentGraceUntil": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"cancelAtPeriodEnd": {
"type": "boolean"
},
"canceledAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"completedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"ownedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"revokedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"installments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"installmentNumber": {
"type": "integer"
},
"status": {
"type": "string"
},
"currency": {
"type": "string"
},
"amountDueCents": {
"type": "integer"
},
"amountPaidCents": {
"type": "integer"
},
"amountRefundedCents": {
"type": "integer"
},
"taxAmountCents": {
"type": "integer"
},
"discountAmountCents": {
"type": "integer"
},
"paidAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"refundedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"disputedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"orderId": {
"type": [
"integer",
"null"
]
}
},
"additionalProperties": true
}
},
"metadata": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/rent-to-own/customer/agreements
List agreements owned by the signed-in customer
- Auth
- Account Bearer JWT
- Scope
- Same buyer-ownership checks as customer agreement detail.
- Request fields
- query developerId: integer
- query status: string
- query limit: integer
- Returns
- HTTP 200: agreements.
Request, response and error reference
Query and header parameters
[
{
"name": "developerId",
"in": "query",
"schema": {
"type": "integer",
"minimum": 1
},
"required": false,
"description": ""
},
{
"name": "status",
"in": "query",
"schema": {
"type": "string"
},
"required": false,
"description": ""
},
{
"name": "limit",
"in": "query",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
},
"required": false,
"description": ""
}
]
No request body fields are read by this operation.
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"agreements": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"developerId": {
"type": "integer",
"minimum": 1
},
"customerUserId": {
"type": [
"integer",
"null"
]
},
"customerId": {
"type": "integer",
"minimum": 1
},
"productId": {
"type": "integer",
"minimum": 1
},
"productName": {
"type": [
"string",
"null"
]
},
"planVersionId": {
"type": "integer",
"minimum": 1
},
"checkoutId": {
"type": [
"integer",
"null"
]
},
"entitlementId": {
"type": [
"integer",
"null"
]
},
"provider": {
"type": "string"
},
"providerSubscriptionId": {
"type": [
"string",
"null"
]
},
"environment": {
"type": "string"
},
"status": {
"type": "string"
},
"accessState": {
"type": "string"
},
"ownershipState": {
"type": "string"
},
"currency": {
"type": "string"
},
"cashPriceCents": {
"type": "integer"
},
"installmentAmountCents": {
"type": "integer"
},
"installmentCount": {
"type": "integer"
},
"totalContractCents": {
"type": "integer"
},
"paidInstallmentCount": {
"type": "integer"
},
"netPaidInstallmentCount": {
"type": "integer"
},
"paidAmountCents": {
"type": "integer"
},
"refundedAmountCents": {
"type": "integer"
},
"disputedAmountCents": {
"type": "integer"
},
"currentPeriodStart": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"currentPeriodEnd": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"nextPaymentAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"failedPaymentGraceUntil": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"cancelAtPeriodEnd": {
"type": "boolean"
},
"canceledAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"completedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"ownedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"revokedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"installments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"installmentNumber": {
"type": "integer"
},
"status": {
"type": "string"
},
"currency": {
"type": "string"
},
"amountDueCents": {
"type": "integer"
},
"amountPaidCents": {
"type": "integer"
},
"amountRefundedCents": {
"type": "integer"
},
"taxAmountCents": {
"type": "integer"
},
"discountAmountCents": {
"type": "integer"
},
"paidAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"refundedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"disputedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"orderId": {
"type": [
"integer",
"null"
]
}
},
"additionalProperties": true
}
},
"metadata": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
}
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 503.
/api/rent-to-own/customer/agreements/{agreementId}/cancel
Cancel a buyer agreement under its saved cancellation policy
- Auth
- Account Bearer JWT
- Scope
- Signed-in buyer only; authenticated identity and route agreement ID cannot be supplied in the body.
- Request fields
- reason: string
- Returns
- HTTP 200: agreement, immediate, unchanged.
- Notes
- Only reason is customer-editable. The saved agreement cancellationBehavior is authoritative, defaulting to access_until_period_end for legacy agreements. Body policy overrides are ignored. Repeated requests preserve local cancellation with unchanged:true. A pending provider step is retried with the same provider idempotency key; a recorded confirmed step is not sent again. Provider failure returns 502 rent_to_own_cancellation_pending with retryable:true and localCancellationSaved:true. Read metadata.providerCancellation.status; pending is not provider confirmation. Retry this same cancellation request, not a checkout or charge. There is no automatic retry timing promise. Completed/owned, refunded, disputed, revoked or ownership-revoked agreements return 409. Period-end cancellation preserves pending, past-due, grace and suspended lifecycle states, so existing expiry checks still run; it does not upgrade them to paid access. Live rent-to-own checkout remains unavailable; this does not enable new production installment sales.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"reason": {
"type": "string"
}
},
"additionalProperties": true
}
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"agreement": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"developerId": {
"type": "integer",
"minimum": 1
},
"customerUserId": {
"type": [
"integer",
"null"
]
},
"customerId": {
"type": "integer",
"minimum": 1
},
"productId": {
"type": "integer",
"minimum": 1
},
"productName": {
"type": [
"string",
"null"
]
},
"planVersionId": {
"type": "integer",
"minimum": 1
},
"checkoutId": {
"type": [
"integer",
"null"
]
},
"entitlementId": {
"type": [
"integer",
"null"
]
},
"provider": {
"type": "string"
},
"providerSubscriptionId": {
"type": [
"string",
"null"
]
},
"environment": {
"type": "string"
},
"status": {
"type": "string"
},
"accessState": {
"type": "string"
},
"ownershipState": {
"type": "string"
},
"currency": {
"type": "string"
},
"cashPriceCents": {
"type": "integer"
},
"installmentAmountCents": {
"type": "integer"
},
"installmentCount": {
"type": "integer"
},
"totalContractCents": {
"type": "integer"
},
"paidInstallmentCount": {
"type": "integer"
},
"netPaidInstallmentCount": {
"type": "integer"
},
"paidAmountCents": {
"type": "integer"
},
"refundedAmountCents": {
"type": "integer"
},
"disputedAmountCents": {
"type": "integer"
},
"currentPeriodStart": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"currentPeriodEnd": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"nextPaymentAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"failedPaymentGraceUntil": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"cancelAtPeriodEnd": {
"type": "boolean"
},
"canceledAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"completedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"ownedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"revokedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"installments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"installmentNumber": {
"type": "integer"
},
"status": {
"type": "string"
},
"currency": {
"type": "string"
},
"amountDueCents": {
"type": "integer"
},
"amountPaidCents": {
"type": "integer"
},
"amountRefundedCents": {
"type": "integer"
},
"taxAmountCents": {
"type": "integer"
},
"discountAmountCents": {
"type": "integer"
},
"paidAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"refundedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"disputedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"orderId": {
"type": [
"integer",
"null"
]
}
},
"additionalProperties": true
}
},
"metadata": {
"type": "object",
"additionalProperties": true,
"description": "Operation-specific extension data; do not put credentials or unnecessary personal information here."
}
},
"additionalProperties": true
},
"immediate": {
"type": "boolean"
},
"unchanged": {
"type": "boolean"
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 409, 500, 502, 503.
Operation errors: rent_to_own_cancellation_pending.
