BillOS v1
Console llms.txt OpenAPI
POST/businesses/{bid}/recurring

Create a recurring document plan

POST /businesses/{bid}/recurring

Requires the documents scope.

The template the scheduler turns into a document every interval: monthly, quarterly or yearly on a fixed day (1..28). Each run creates an ordinary draft (or issues, with autoIssue) filed under externalRef: recurring:<planId>:<runDate>, and writes a recurring.ran event that says what happened. Runs happen once a day, early morning Israel time; POST .../run produces today's document now.

Path parameters

NameTypeDescription
bidstringrequiredBusiness id, from POST /businesses.

Body

FieldTypeDescription
docTypeinteger300 / 305 / 320 / 400 One of: 300, 305, 320, 400.
partyIdstringA saved party (recommended: a recurring document has a recurring customer).
priceModestringOne of: net, gross. Default net.
currencystringOne of: ILS, USD, EUR, GBP, CHF, AUD, CAD. Default ILS.
fxRatenumberFix the rate for every run (a contract in dollars at an agreed rate). Omit to use the Bank of Israel rate of each run date.
langstringOne of: he, en. Default he.
brandingThemeIdstringThe branding theme it prints in (GET /businesses/{bid}/branding-themes). Omit or null for the customer's default, else the main design; "main" for the main design whatever the customer's default. Frozen at issue: the issued row names the theme it used, null for the main design.
zeroVatboolean
linesarray of DocumentLineRequired for 300/305/320.
paymentsarray of PaymentRequired for 320/400; must cover the total exactly as on a one-off document.
discountAmountintegerInteger agorot (₪1 = 100).
notestring≤500 chars, printed on every document the plan produces.
intervalstringOne of: monthly, quarterly, yearly. Default monthly.
dayOfMonthinteger1..28. Default 1.
nextRunOnstringFirst run. Default: the plan's day this month if still ahead, else next month.
endOnstringLast possible run date; the plan pauses itself after it.
autoIssuebooleanDefault false: each run leaves a DRAFT to review. true: each run ISSUES (a permanent, numbered document with nobody looking), which is what a subscription business wants and what a first-time integrator should not switch on before watching a few drafts.
activebooleanfalse pauses the plan.

Response

201: { "ok": true, … }

FieldTypeDescription
okbooleanrequired
planRecurringPlanrequiredA template the scheduler turns into a draft (or an issued document, with autoIssue) every interval. Not a document: freely editable and deletable.

Errors: 400, 401, 403, 404, 429. Every failure answers { "error", "reason", "hint", "param", "doc_url", "retryable", "request_id" }: branch on reason, and read hint for what to change (https://docs.billos.co.il/errors.md).

POST /businesses/{bid}/recurring
curl -X POST "$BASE/businesses/$BID/recurring" \
  -H "X-Api-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "priceMode": "gross",
    "lines": [
      {
        "description": "איפור כלה",
        "quantity": 1,
        "unitPriceExVat": 120000
      }
    ],
    "payments": [
      {
        "method": 3,
        "amount": 120000
      }
    ]
  }'
const res = await fetch(`${BASE}/businesses/${BID}/recurring`, {
  method: 'POST',
  headers: {
    'X-Api-Key': KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "priceMode": "gross",
    "lines": [
      {
        "description": "איפור כלה",
        "quantity": 1,
        "unitPriceExVat": 120000
      }
    ],
    "payments": [
      {
        "method": 3,
        "amount": 120000
      }
    ]
  }),
})
const data = await res.json()
if (!data.ok) throw new Error(data.reason)
import requests
res = requests.post(
    f"{BASE}/businesses/{BID}/recurring",
    headers={"X-Api-Key": KEY},
    json={
      "priceMode": "gross",
      "lines": [
        {
          "description": "איפור כלה",
          "quantity": 1,
          "unitPriceExVat": 120000
        }
      ],
      "payments": [
        {
          "method": 3,
          "amount": 120000
        }
      ]
    },
)
data = res.json()
Set BASE to https://api.billos.co.il/v1 and KEY to your bk_live_… key, or a bk_test_… key to run it against the sandbox.
Manage your businesses, keys and webhooks in the BillOS Console.