Tabba.
IntegrationerSådan virker TabbaFeatures

© 2026 Tabba. Alle rettigheder forbeholdes.

Udviklere
Udviklere
Udviklere
Overview
Take a line of a recurring series away DELETEList the recurring series of the company GETRead one recurring series GETList the occurrences of a recurring series GETRead one occurrence of a recurring series GETChange the header fields of a recurring series that the body states PATCHChange a line of a recurring series PATCHCreate a recurring series POSTCancel a recurring series POSTAdd a line to a recurring series POSTIssue an occurrence of a recurring series now POST

Andre spor

AI clientsREST API
Recurring series

Change the header fields of a recurring series that the body states

A field the body leaves out stays as it is. The lines are not touched, except that a change of start_date or frequency moves every period and so resets each line to what it started with. Once the series has issued an invoice its customer, currency, schedule and title are locked (SERIES_SETUP_LOCKED, 409); layout_ref never is. Moving end_date on such a series ends it by that date, exactly as the cancel route does, with the credit notes an end books; the cancel route is the one that reports them. A schedule that leaves out occurrences with registered work is refused (SCHEDULE_DROPS_REGISTERED_WORK, 409) until the body states acknowledge_dropped_work, and a change met by an occurrence that is being issued is refused whole (ISSUE_IN_PROGRESS, 409).

PATCH
/recurring-series/{ref}

Authorization

bearerAuth
AuthorizationBearer <token>

An API key minted by an admin under Settings → Developers. It is bound to one company and has a scope: read, or read_write. A request without one, or with one that is not ours, is answered 401 and metered by its client address (x-rate-limits).

In: header

Path Parameters

ref*string

The record's id, or ext:<external_id> for the record that carries your own key.

Request 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

application/json

application/json

curl -X PATCH "https://example.com/recurring-series/string" \  -H "Content-Type: application/json" \  -d '{}'
{  "object": "recurring_series",  "id": "string",  "external_id": "string",  "customer_id": "string",  "customer_name": "string",  "currency": "string",  "frequency": "monthly",  "start_date": "string",  "end_date": "string",  "issue_timing": {    "mode": "start-of-period"  },  "title": "string",  "use_billing_period_as_title": true,  "layout_ref": "string",  "status": "draft",  "cancelled_at": "string",  "created_at": "string",  "updated_at": "string",  "lines": [    {      "id": "string",      "product_id": "string",      "product_number": "string",      "product_name": "string",      "recognition_method": "value",      "agreed_value": 0,      "hourly_rate": 0,      "discount": 0,      "description_override": "string",      "position": -9007199254740991,      "assignees": [        {          "user_id": "string",          "distribution_percentage": 0,          "hourly_rate_override": 0,          "removed": true        }      ]    }  ]}

Read one occurrence of a recurring series GET

The occurrence with its lines. One that is not issued states what the series’ lines come to on it after every change, with a final partial period’s value lines prorated; one that is issued states the lines its invoice was issued with. **Reading it never makes it an invoice**: an occurrence that is none yet answers `invoice_id: null`. A date that starts no period of the series is `OCCURRENCE_OUT_OF_RANGE` (404).

Change a line of a recurring series PATCH

The fields the body states are changed as the line stands on the occurrence `period` names. With `this-and-following` the change holds from that occurrence on, and earlier occurrences keep what they had. With `this-only` it holds on that occurrence alone, and what the line says before and after is left as it is. The result is what the same edit in the workspace leaves: on the first occurrence every change is the line’s own start, whatever scope is asked; the product always holds from the occurrence on; and a field an occurrence already states for itself stays its own until that field is changed for this and following. A one-time line is on one occurrence, so either scope changes it in place. The same change sent again writes nothing more. Refused with `OCCURRENCE_ISSUED` (409) when the occurrence is issued, and with `SERIES_LINE_NOT_FOUND` (404) when the line is not on that occurrence.

customer?string

The customer billed: its id, or ext:<external_id>.

Length1 <= length <= 255
currency?string

ISO 4217.

Length3 <= length <= 3
frequency?string

Value in

  • "monthly"
  • "quarterly"
  • "semi-annual"
  • "annual"
start_date?string

YYYY-MM-DD.

end_date?|

YYYY-MM-DD, inclusive, or null for no end.

issue_timing?||

When in its period an occurrence is issued. Never later than the end date of the series.

title?|null
use_billing_period_as_title?boolean
layout_ref?|null
external_id?|null
acknowledge_dropped_work?boolean

True: occurrences the change leaves out are dropped with the work registered on them. Without it such a change is refused with SCHEDULE_DROPS_REGISTERED_WORK.