Create tax code

POST /api/configuration/tax-codes

Overview

Creates a tax code — a named tax rate that products and invoice lines are charged under. A tax code holds a description, a percentage rate and an optional reference; it does not know anything about jurisdictions or which products use it. Products carry the tax code's id, and each invoice line records both the id and the rate at the moment it is quoted, so changing a rate later does not restate anything already quoted or invoiced. If a rate changes, create a new tax code rather than editing the old one.

The identifier is a short string. You choose it yourself by sending id, or you omit id and one is allocated for you: the endpoint takes the highest existing id beginning TAXC, adds one, and zero-pads the number to a total length of 15 characters, giving ids of the form TAXC00000000001. Either way the id that was used comes back in the response body:

201 Created
{ "id": "TAXC00000000001" }

Read that property case-insensitively, and take the id from it rather than assuming the value you sent was stored verbatim — an id you supply is upper-cased and has its spaces removed first. The endpoint also sets a Location header.

Retrying is only safe when you choose the id yourself: a second request with an id that already exists is rejected with 409 Conflict and nothing is saved. If you omit id, each retry allocates a new id and creates another tax code — there is no duplicate detection on description or rate, and nothing stops you holding two tax codes at 20%.

The id is the only thing that has to be unique. Note that its 15-character limit is not checked by request validation on this endpoint, so an over-long id is not caught by validation and fails as a 500 instead of a 400.

Endpoint

POST {base_url}/api/configuration/tax-codes

{base_url} is the environment URL issued to your integration. See Authenticating with Gladstone APIs.

Request body

FieldTypeRequiredDescription
idstringNoThe identifier you want the tax code to have. It is upper-cased and has spaces stripped before storage, so vat std is saved and must later be referenced as VATSTD, and it must not already be in use. Unlike most ids on this API it is not length-checked by request validation, but the maximum is 15 characters, so anything longer fails with 500 rather than 400. Omit the field and the endpoint allocates the next id in the TAXC… sequence and returns it to you.
descriptionstringYesThe name of the tax code as it appears to staff — "Standard rate", "Zero rated" and so on. Must not be empty and must be 25 characters or fewer. The rejection message for this field reads The price level description cannot be more than 25 characters; that mention of price levels is an error in the message, which does refer to this field.
ratenumber (double)NoThe tax percentage, expressed as a number out of 100 rather than a fraction: send 20 for 20%, not 0.2. It must be between 0 and 100 inclusive and must have no more than two decimal places — 17.5 is accepted, 17.501 is rejected with 400. 0 is valid and is how you record a zero-rated code. Omitting the field is the same as sending 0, so a tax code created without a rate charges nothing. The value is stored with single precision, so do not expect exact round-tripping of values beyond two decimal places.
referencestringNoA free-text reference of up to 25 characters stored alongside the tax code and returned by the retrieval endpoints. Defaults to an empty string when omitted. Its rejection message also mentions "price level reference", which is the same error.
translationsarray of objectNoTranslations of this tax code's description for bilingual sites. Omit or send an empty array if you only need the description. Entries are stored as supplied without any validation, so a mistake here surfaces as a 500 rather than a 400.
translations[].typestringNoThe name of the field being translated. Use description — that is the only property the tax code retrieval and list endpoints read back, so an entry with any other value is stored but never returned.
translations[].culturestringNoThe culture code the translation is for, for example cy-GB. It must be a culture code the platform already knows about; an unrecognised code fails the request with 500.
translations[].textstringNoThe translated text itself — what description should read as in that culture.

Sample request

cURL
curl -X POST '{base_url}/api/configuration/tax-codes' \
  -H 'Authorization: Bearer {accessToken}' \
  -H 'X-Use-SSO: true' \
  -H 'Content-Type: application/json' \
  -d '{
  "id": "string",
  "description": "string",
  "rate": 10.5,
  "reference": "string",
  "translations": [
    {
      "type": "string",
      "culture": "string",
      "text": "string"
    }
  ]
}'

Errors

Request validation failures return a validation problem document (application/problem+json) with an errors map keyed by field name. The other failures return the message below as a plain string body.

StatusMeaningWhen
400Bad requestRequest validation failed before any other check: description missing, empty or longer than 25 characters (The description must not be empty, The price level description cannot be more than 25 characters), rate outside 0–100 (Rate has to be between 0 and 100 inclusive), or reference longer than 25 characters (The price level reference cannot be more than 25 characters).
400Bad requestMalformed JSON, or a value of the wrong type — including null sent for rate, which is not a nullable field.
400Bad requestrate has more than two decimal places. Body: The tax rate can only be specified to two decimal places. This is checked before anything else, so it masks a duplicate id.
409ConflictThe id you supplied is already in use, compared after upper-casing and removing spaces. Body: The TaxCode {id} already exists. Nothing is created.
409ConflictA concurrent request created a tax code with the same id at the same moment. Body: This entry already exists in the database.
500Internal server errorThe id you supplied is longer than 15 characters. Request validation does not check this, so it fails when the tax code is saved.
500Internal server errorA translations[].culture is not a culture code the platform recognises, so the translation cannot be saved.
500Internal server errorAny other unexpected server-side failure.

This page as markdown · All pages · llms.txt