Update workspace settings
const url = 'http://localhost:8080/v1/settings';const options = { method: 'PUT', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"default_currency":"USD","timezone":"UTC","invoice_prefix":"example","credit_note_prefix":"example","net_payment_terms":1,"credit_balance_low_threshold_cents":1,"tax_provider":"none","tax_rate":1,"tax_name":"example","tax_inclusive":true,"tax_on_failure":"block","default_product_tax_code":"example","company_name":"example","company_address_line1":"example","company_address_line2":"example","company_city":"example","company_state":"example","company_postal_code":"example","company_country":"example","company_email":"example","company_phone":"example","logo_url":"example","brand_color":"example","tax_id":"example","support_url":"example","invoice_footer":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PUT \ --url http://localhost:8080/v1/settings \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "default_currency": "USD", "timezone": "UTC", "invoice_prefix": "example", "credit_note_prefix": "example", "net_payment_terms": 1, "credit_balance_low_threshold_cents": 1, "tax_provider": "none", "tax_rate": 1, "tax_name": "example", "tax_inclusive": true, "tax_on_failure": "block", "default_product_tax_code": "example", "company_name": "example", "company_address_line1": "example", "company_address_line2": "example", "company_city": "example", "company_state": "example", "company_postal_code": "example", "company_country": "example", "company_email": "example", "company_phone": "example", "logo_url": "example", "brand_color": "example", "tax_id": "example", "support_url": "example", "invoice_footer": "example" }'Merges the body into the current settings. A field you leave out
keeps its stored value. A field you send is set, even to "" or
0. Send credit_balance_low_threshold_cents: null to turn
low-balance alerts off.
Empty default_currency, timezone, invoice_prefix,
credit_note_prefix, tax_provider and tax_on_failure fall back
to their defaults.
default_currency, company_country, invoice_prefix and
credit_note_prefix are stored in upper case, and brand_color in
lower case. Choosing stripe_tax with no
default_product_tax_code sets it to txcd_10103001 (SaaS,
business use).
A save that changes a field writes one audit row listing each change.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”Makes the call safe to retry. Send a unique value (a UUID works) and
the same value on every retry. For 24 hours, a repeat with the same
key, method, path and body gets the first response again, with an
Idempotent-Replayed: true header, instead of running again. The
error cases are in docs/api-surface.md. The usage routes do not take
it: each usage event carries its own idempotency_key.
Request Bodyrequired
Section titled “Request Bodyrequired”Every field is optional. Fields you leave out keep their stored value.
object
ISO 4217 code. Zero-decimal currencies (such as JPY) are not supported yet.
Example
USDIANA zone name, such as America/New_York. Local is rejected. All billing date math uses this zone.
Example
UTCStarts every invoice number, such as HC-000001.
Starts every credit note number, such as CN-000001. A change
applies to new credit notes only. Issued notes keep their
numbers. It must differ from invoice_prefix, or an invoice and
a credit note would get the same number.
Days until an invoice is due. 0 means due on issue.
When a customer’s credit in one currency drops below this
amount, in that currency’s minor units, the credit.balance_low
webhook fires: 1000 means $10.00 of USD credit and €10.00 of EUR
credit. null turns it off.
none = no tax, manual = the flat tax_rate, stripe_tax = Stripe Tax.
Percent, up to 4 decimal places (18.5 = 18.5%). Used by the manual provider.
Label for the tax line, such as VAT.
Whether prices already include tax.
What to do when the tax provider fails. block holds the invoice until tax succeeds.
Stripe product tax code used when a plan has none, such as
txcd_10103001. Empty is allowed. Surrounding whitespace is
trimmed before the check.
Shown on invoices and as the sender name on emails. No line breaks.
ISO 3166 alpha-2 code, such as US. Empty is allowed.
Whitespace is trimmed and the code is upper-cased before it is
checked and stored.
7 to 20 characters of digits, spaces, +, -, ( and ).
Shown in emails and on the hosted invoice page. PDFs do not print it.
Accent color on invoice PDFs, as #rrggbb.
Your own tax number (VAT, EIN, GSTIN), printed on invoices.
Must start with http:// or https://. Linked in emails and on
the hosted invoice page, and printed at the foot of invoice and
credit-note PDFs.
Printed under the totals on invoice PDFs and on the hosted invoice page. Each invoice keeps the footer it was issued with, so a change applies to invoices issued after it. A draft shows the current text.
Responses
Section titled “Responses”Saved settings
object
ISO 4217 code. Zero-decimal currencies (such as JPY) are not supported yet.
IANA zone name, such as America/New_York. Local is rejected. All billing date math uses this zone.
Starts every invoice number, such as HC-000001.
Starts every credit note number, such as CN-000001. A change
applies to new credit notes only. Issued notes keep their
numbers. It must differ from invoice_prefix, or an invoice and
a credit note would get the same number.
Days until an invoice is due. 0 means due on issue.
When a customer’s credit in one currency drops below this
amount, in that currency’s minor units, the credit.balance_low
webhook fires: 1000 means $10.00 of USD credit and €10.00 of EUR
credit. null turns it off.
none = no tax, manual = the flat tax_rate, stripe_tax = Stripe Tax.
Percent, up to 4 decimal places (18.5 = 18.5%). Used by the manual provider.
Label for the tax line, such as VAT.
Whether prices already include tax.
What to do when the tax provider fails. block holds the invoice until tax succeeds.
Stripe product tax code used when a plan has none, such as
txcd_10103001. Empty is allowed. Surrounding whitespace is
trimmed before the check.
Shown on invoices and as the sender name on emails. No line breaks.
ISO 3166 alpha-2 code, such as US. Empty is allowed.
Whitespace is trimmed and the code is upper-cased before it is
checked and stored.
7 to 20 characters of digits, spaces, +, -, ( and ).
Shown in emails and on the hosted invoice page. PDFs do not print it.
Accent color on invoice PDFs, as #rrggbb.
Your own tax number (VAT, EIN, GSTIN), printed on invoices.
Must start with http:// or https://. Linked in emails and on
the hosted invoice page, and printed at the foot of invoice and
credit-note PDFs.
Printed under the totals on invoice PDFs and on the hosted invoice page. Each invoice keeps the footer it was issued with, so a change applies to invoices issued after it. A draft shows the current text.
The number the next invoice in this mode (test or live) gets,
before the prefix: 43 means the next invoice is
<invoice_prefix>-000043. Test and live count separately, and
changing invoice_prefix keeps the count. Not a setting:
sending it on PUT does nothing.
Zero time when the tenant has never saved settings.
Example
{ "default_currency": "USD", "timezone": "UTC", "tax_provider": "none", "tax_on_failure": "block"}Body is not valid JSON
object
object
One of invalid_request_error, authentication_error,
rate_limit_error or api_error. Every error the API
answers has this shape, including an unknown path (404,
code route_not_found) and a method the path does not take
(405, code method_not_allowed, with an Allow header).
The few exceptions are listed in docs/api-surface.md.
The request field the error is about. Sent only when the error
names one. A request body may hold only the fields its
operation lists, spelled and cased as listed: any other
field, or one the server sets (such as id), is refused
with 422 and param naming it. An operation with no request body lists no fields: send
no body, {} or null. The Stripe and Postmark webhooks and
the LiteLLM callback take their sender’s body as it comes.
Example
{ "error": { "type": "invalid_request_error" }}Caller lacks the apikey:write permission
object
object
One of invalid_request_error, authentication_error,
rate_limit_error or api_error. Every error the API
answers has this shape, including an unknown path (404,
code route_not_found) and a method the path does not take
(405, code method_not_allowed, with an Allow header).
The few exceptions are listed in docs/api-surface.md.
The request field the error is about. Sent only when the error
names one. A request body may hold only the fields its
operation lists, spelled and cased as listed: any other
field, or one the server sets (such as id), is refused
with 422 and param naming it. An operation with no request body lists no fields: send
no body, {} or null. The Stripe and Postmark webhooks and
the LiteLLM callback take their sender’s body as it comes.
Example
{ "error": { "type": "invalid_request_error" }}A field failed validation. error.param names the field.
object
object
One of invalid_request_error, authentication_error,
rate_limit_error or api_error. Every error the API
answers has this shape, including an unknown path (404,
code route_not_found) and a method the path does not take
(405, code method_not_allowed, with an Allow header).
The few exceptions are listed in docs/api-surface.md.
The request field the error is about. Sent only when the error
names one. A request body may hold only the fields its
operation lists, spelled and cased as listed: any other
field, or one the server sets (such as id), is refused
with 422 and param naming it. An operation with no request body lists no fields: send
no body, {} or null. The Stripe and Postmark webhooks and
the LiteLLM callback take their sender’s body as it comes.
Example
{ "error": { "type": "invalid_request_error" }}