Retainers

Standing arrangements that issue the same document on a schedule — a monthly invoice, a fortnightly bill. An INVOICE_RECEIPT retainer also charges a saved card on each run.

Use cases: Use this for subscriptions and ongoing fees: define the document once, and let each cycle issue it (and collect it) on its own.
GET/retainers

List retainers.

**Not paginated** — every retainer comes back, newest first, and `limit`/`offset`/`page` are ignored. Deleted retainers are excluded. `chargeFailureCount` and `lastChargeError` are how you spot a saved card that has started declining.

Request

curl -X GET "https://api.glance.co.il/retainers" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

Response

Response
{
  "success": true,
  "data": [
    {
      "id": 1,
      "type": "INVOICE",
      "description": "ריטיינר חודשי",
      "entityId": 7742,
      "amount": 2000,
      "tax": 360,
      "totalWithTax": 2360,
      "intervalDays": null,
      "scheduleDay": 1,
      "nextRunDate": "2026-09-01T00:00:00.000Z",
      "endDate": null,
      "maxRuns": null,
      "runsCount": 7,
      "ignoredDaysOfWeek": [],
      "isActive": true,
      "paymentTokenId": null,
      "chargeAmount": null,
      "chargeFailureCount": 0,
      "lastChargeError": null,
      "lastChargeAt": null,
      "prorateFirstRun": false,
      "creationDate": "2026-02-01T09:00:00.000Z",
      "client": {
        "id": 7742,
        "name": "אלקבץ בע״מ",
        "address": null,
        "logoFile": null
      }
    }
  ]
}
GET/retainers/:id

Get a single retainer.

404 RETAINER_NOT_FOUND when the id is unknown. `raw` holds the document body each run is issued from.

Path Parameters

NameTypeDescription
id
numberrequiredThe retainer's numeric id.

Request

curl -X GET "https://api.glance.co.il/retainers/:id" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

Response

Response
{
  "success": true,
  "data": {
    "id": 1,
    "type": "INVOICE",
    "entityId": 7742,
    "amount": 2000,
    "tax": 360,
    "totalWithTax": 2360,
    "raw": {
      "…": "the document template this retainer issues"
    },
    "scheduleDay": 1,
    "nextRunDate": "2026-09-01T00:00:00.000Z",
    "runsCount": 7,
    "isActive": true,
    "client": {
      "id": 7742,
      "name": "אלקבץ בע״מ"
    }
  }
}
POST/retainers/create

Create a retainer.

`firstRun` is present only when `runFirstNow` was set. A `documentError` alongside `issued: true` means the money moved but the PDF did not come out — the request is not a failure and must not be retried, since a retry would charge the client twice. `POST /retainers/preview` takes the same body and returns the first document as a PDF (`Content-Type: application/pdf`) without saving anything.

Body Parameters

NameTypeDescription
type
stringrequired"BILL", "INVOICE" or "INVOICE_RECEIPT". An INVOICE_RECEIPT asserts that payment was received, so it may only be created against a saved card — `paymentTokenId` and `chargeAmount` are then both required.
clientId
numberrequiredThe client's numeric entity id.
products
object[]requiredThe line items each issued document carries. Same shape as the line items on `POST /documents/create/{type}`. At least one is required.
intervalDays
numberRun every N days. Either this or `scheduleDay` is required — a retainer with neither is rejected.
scheduleDay
numberRun monthly on this day of the month, 1–31. A month shorter than the chosen day runs on its last day.
endDate
stringStop running after this date (YYYY-MM-DD).
maxRuns
numberStop after this many documents. Omit for unlimited.
ignoredDaysOfWeek
number[]Weekdays to skip, 0 (Sunday) to 6 (Saturday). A run landing on one moves off it.
firstRunDate
stringWhen the first run happens (YYYY-MM-DD). Every run after it follows the cadence. Omitted, the first run is derived from `date`.
runFirstNow
booleanIssue — and, for an INVOICE_RECEIPT, charge — the first document as part of this request, rather than waiting for the nightly run. The first run date is then today, whatever `firstRunDate` says.
prorateFirstRun
booleanCharge only the remainder of the current cycle on the first run, so every run after it lands on `scheduleDay`. Monthly schedules only. Left off while `scheduleDay` differs from the first run's own day, the first run comes out in full and the rest still align to `scheduleDay`.
paymentTokenId
numberThe saved card to charge on every run. See the Saved Cards section.
chargeAmount
numberThe full per-run total including VAT. For an INVOICE_RECEIPT this is what the card is charged; for every other type it is the base a pro-rated first run takes its fraction of. Frozen at creation — what the client is charged must equal what the document says.
title
stringDocument title.
payBy
stringDue date on the issued document (YYYY-MM-DD).
date
stringDocument date (YYYY-MM-DD). Also where the first run is derived from when `firstRunDate` is not given.
currencyCode
stringThree-letter document currency.
tax
numberVAT rate override.
discount
numberDocument-level discount.
discountType
string"absolute" or "percents".
taxMode
string"beforeTax" or "includeTax".
notes
stringNotes printed on every issued document.
textAboveProducts
stringFree text printed above the line items.
withSignature
string[]Signature blocks to print: "company", "client".
signatureFileId
numberId of an uploaded signature image.
producerType
string[]Who is credited as producer: "user", "platform".
relatedDocuments
object[]Documents each issued document draws from, as `{ id, amount, products }`.
skipInventoryActions
booleanIssue without moving stock. Defaults to false.
sendToClient
booleanEmail each issued document to the client. Defaults to false.
emailRecipients
string[]Extra email recipients.

Request

curl -X POST "https://api.glance.co.il/retainers/create" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "type": "example_type",
  "clientId": 0,
  "products": "example_products",
  "intervalDays": 0,
  "scheduleDay": 0,
  "endDate": "example_endDate",
  "maxRuns": 0,
  "ignoredDaysOfWeek": "example_ignoredDaysOfWeek",
  "firstRunDate": "example_firstRunDate",
  "runFirstNow": true,
  "prorateFirstRun": true,
  "paymentTokenId": 0,
  "chargeAmount": 0,
  "title": "example_title",
  "payBy": "example_payBy",
  "date": "example_date",
  "currencyCode": "example_currencyCode",
  "tax": 0,
  "discount": 0,
  "discountType": "example_discountType",
  "taxMode": "example_taxMode",
  "notes": "example_notes",
  "textAboveProducts": "example_textAboveProducts",
  "withSignature": "example_withSignature",
  "signatureFileId": 0,
  "producerType": "example_producerType",
  "relatedDocuments": "example_relatedDocuments",
  "skipInventoryActions": true,
  "sendToClient": true,
  "emailRecipients": "example_emailRecipients"
}'

Response

Response
{
  "success": true,
  "retainerId": 1,
  "retainer": {
    "…": "the created retainer row"
  },
  "firstRun": {
    "issued": true,
    "documentId": 84995,
    "documentError": null
  }
}
PUT/retainers/:id

Update a retainer, including its card and charge amount. All fields are optional.

**Omitting a field means "leave it as it is", so `null` is the only way to remove a value.** It clears `intervalDays`, `scheduleDay`, `endDate`, `maxRuns`, `paymentTokenId` and `chargeAmount`; on every other field `null` is rejected. 400 RETAINER_SCHEDULE_REQUIRED when the update would leave the retainer with neither `intervalDays` nor `scheduleDay` — the check is against the row's resulting state, so clearing the only cadence that is set is refused even when the body names just that one field. `nextRunDate` is not recalculated here — it is set at creation and advanced by each run, so changing the cadence takes effect from the run after next. `PUT /retainers/edit/:id` is a narrower variant of the same update that does not touch the saved card or the charge amount; it takes the same scheduling fields with the same `null` semantics.

Path Parameters

NameTypeDescription
id
numberrequiredThe retainer's numeric id.

Body Parameters

NameTypeDescription
type
string"BILL", "INVOICE" or "INVOICE_RECEIPT".
clientId
numberThe client's numeric entity id.
products
object[]Replacement line items. Sending this replaces the whole list.
paymentTokenId
numberThe saved card to charge. `null` detaches the card and stops charging.
chargeAmount
numberPer-run total including VAT. `null` clears it.
isActive
booleanPause or resume the retainer.
intervalDays
numberRun every N days. `null` clears it — that is how you move a retainer off an interval and onto a monthly day, and the switch does nothing without it. Either this or `scheduleDay` must survive the update; clearing both is rejected.
scheduleDay
numberRun monthly on this day of the month, 1–31. A month shorter than the chosen day runs on its last day. `null` clears it — that is how you move back to an interval, and the switch does nothing without it, because a retainer that has both runs on `scheduleDay`.
endDate
stringStop running after this date (YYYY-MM-DD). `null` removes the end date and the retainer runs indefinitely again; omitting it leaves whatever is on the row.
maxRuns
numberStop after this many documents. `null` removes the limit; omitting it leaves whatever is on the row — unlike on create, where omitting means unlimited.
ignoredDaysOfWeek
number[]Weekdays to skip, 0 (Sunday) to 6 (Saturday). A run landing on one moves off it.
title
stringDocument title.
payBy
stringDue date on the issued document (YYYY-MM-DD).
date
stringDocument date (YYYY-MM-DD). Also where the first run is derived from when `firstRunDate` is not given.
currencyCode
stringThree-letter document currency.
tax
numberVAT rate override.
discount
numberDocument-level discount.
discountType
string"absolute" or "percents".
taxMode
string"beforeTax" or "includeTax".
notes
stringNotes printed on every issued document.
textAboveProducts
stringFree text printed above the line items.
withSignature
string[]Signature blocks to print: "company", "client".
signatureFileId
numberId of an uploaded signature image.
producerType
string[]Who is credited as producer: "user", "platform".
relatedDocuments
object[]Documents each issued document draws from, as `{ id, amount, products }`.
skipInventoryActions
booleanIssue without moving stock. Defaults to false.
sendToClient
booleanEmail each issued document to the client. Defaults to false.
emailRecipients
string[]Extra email recipients.

Request

curl -X PUT "https://api.glance.co.il/retainers/:id" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "type": "example_type",
  "clientId": 0,
  "products": "example_products",
  "paymentTokenId": 0,
  "chargeAmount": 0,
  "isActive": true,
  "intervalDays": 0,
  "scheduleDay": 0,
  "endDate": "example_endDate",
  "maxRuns": 0,
  "ignoredDaysOfWeek": "example_ignoredDaysOfWeek",
  "title": "example_title",
  "payBy": "example_payBy",
  "date": "example_date",
  "currencyCode": "example_currencyCode",
  "tax": 0,
  "discount": 0,
  "discountType": "example_discountType",
  "taxMode": "example_taxMode",
  "notes": "example_notes",
  "textAboveProducts": "example_textAboveProducts",
  "withSignature": "example_withSignature",
  "signatureFileId": 0,
  "producerType": "example_producerType",
  "relatedDocuments": "example_relatedDocuments",
  "skipInventoryActions": true,
  "sendToClient": true,
  "emailRecipients": "example_emailRecipients"
}'

Response

Response
{
  "success": true,
  "data": {
    "…": "the updated retainer row"
  }
}
DELETE/retainers/:id

Deactivate a retainer, or delete an already-inactive one.

Call it twice to remove a retainer: the first call on an active retainer only deactivates it (`isActive: false`), and a second call then deletes it. The message tells you which happened. Deleting is a soft delete — the row keeps its history and drops out of `GET /retainers`.

Path Parameters

NameTypeDescription
id
numberrequiredThe retainer's numeric id.

Request

curl -X DELETE "https://api.glance.co.il/retainers/:id" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

Response

Response
{
  "success": true,
  "message": "Retainer deactivated successfully"
}
POST/retainers/reactivate/:id

Reactivate a deactivated retainer.

A retainer that is already active answers 400 RETAINER_ALREADY_ACTIVE.

Path Parameters

NameTypeDescription
id
numberrequiredThe retainer's numeric id.

Request

curl -X POST "https://api.glance.co.il/retainers/reactivate/:id" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

Response

Response
{
  "success": true,
  "message": "Retainer reactivated successfully"
}
GET/retainers/:id/one-time-items

List the one-off charges queued on a retainer — an extra that rides along on one billing cycle without changing the recurring amount.

Returns APPLIED and CANCELLED items too, on purpose: an applied item is the explanation for why one document differs from the rest, and a cancelled one is the record that somebody decided to drop it.

Path Parameters

NameTypeDescription
id
numberrequiredThe retainer ID.

Request

curl -X GET "https://api.glance.co.il/retainers/:id/one-time-items" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

Response

Response
{
  "success": true,
  "items": [
    {
      "id": 71,
      "retainerId": 1,
      "recurringPaymentId": null,
      "description": "התקנה חד-פעמית",
      "units": 1,
      "price": 450,
      "productId": null,
      "applyOn": null,
      "status": "PENDING",
      "createdBy": 12
    }
  ]
}
POST/retainers/:id/one-time-items

Queue a one-off charge onto a retainer's next document.

An item is marked APPLIED only after the document is issued. If the charge or the issue fails, it stays PENDING and rides on the next cycle instead of disappearing silently.

Path Parameters

NameTypeDescription
id
numberrequiredThe retainer ID.

Body Parameters

NameTypeDescription
description
stringrequiredLine description, as it will be printed.
units
numberQuantity. Must be positive. Defaults to 1.
price
numberrequiredPrice per unit.
productId
numberOptional catalogue product to link the line to.
applyOn
stringISO 8601 timestamp of the cycle this item is meant for. Empty means the next cycle; a future date keeps it waiting until that cycle comes round.

Request

curl -X POST "https://api.glance.co.il/retainers/:id/one-time-items" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "description": "example_description",
  "units": 0,
  "price": 0,
  "productId": 0,
  "applyOn": "example_applyOn"
}'

Response

Response
{
  "success": true,
  "id": 71
}
PUT/retainers/:id/one-time-items/:itemId

Edit a queued one-off charge.

Only a PENDING item can be edited. Once it has gone out on a document, editing returns 400 INVALID_STATUS — the document was issued and possibly paid, so changing the line here would rewrite history without changing anything real.

Path Parameters

NameTypeDescription
id
numberrequiredThe retainer ID.
itemId
numberrequiredThe one-time item ID.

Body Parameters

NameTypeDescription
description
stringLine description.
units
numberQuantity.
price
numberPrice per unit.
productId
numberLinked product, or null to unlink.
applyOn
stringTarget cycle, or null for the next one.

Request

curl -X PUT "https://api.glance.co.il/retainers/:id/one-time-items/:itemId" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "description": "example_description",
  "units": 0,
  "price": 0,
  "productId": 0,
  "applyOn": "example_applyOn"
}'

Response

Response
{
  "success": true
}
DELETE/retainers/:id/one-time-items/:itemId

Cancel a queued one-off charge.

Cancels rather than deletes — the row stays, with status CANCELLED, so the decision is visible on the retainer screen. An item already APPLIED cannot be cancelled (400 INVALID_STATUS): credit the document instead. The same four routes exist under /grow/recurring-payments/:id/one-time-items for standing orders.

Path Parameters

NameTypeDescription
id
numberrequiredThe retainer ID.
itemId
numberrequiredThe one-time item ID.

Request

curl -X DELETE "https://api.glance.co.il/retainers/:id/one-time-items/:itemId" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

Response

Response
{
  "success": true
}

Last updated