Skip to main content

Quaderno API (current version 20241028)

Download OpenAPI specification:Download

Quaderno helps you scale your business without stressing about taxes. Our powerful REST API solves all your tax compliance needs:

  • Accurate tax calculation on every sale, worldwide.
  • Billing with automatic invoices and credit notes.
  • Alerts for new tax obligations and registrations.
  • Tax reports by country or state.
  • Quaderno Checkout, if you don't have your own checkout.

Here you can check our OpenAPI reference. Don't miss our developer tools and guides too!

API features

Authentication

Quaderno uses an API key to authorize all requests, allowing access to the API in combination with the account name in the endpoint URL. You can find your API keys in quadernoapp.com/users/api-keys.

Quaderno expects the API key to be included via HTTP Basic Auth in all API requests to the server. When using curl, it looks like the following:

-u <YOUR_API_KEY>:x

Note that x is just a placeholder, only the API key will be taken into consideration.

Using that modifier on curl will send a request with an HTTP header like Authorization: Basic xxxx.

This would be a simple example of an authenticated GET request:

curl https://ACCOUNT_NAME.quadernoapp.com/api/invoices.json \
  -u <YOUR_API_KEY>:x

You can also /ping to check if the service is up, your credentials are correct, or to know your remaining requests without doing an actual request:

curl https://quadernoapp.com/api/ping \
  -u <YOUR_API_KEY>:x

Remember that anyone who has your private key can see and change everything that you have access to. Make sure to keep it, and your password, safe.

Authorization

To learn the ACCOUNT_NAME for your target account, you can get it with the /authorization API call.

This returns the following as a JSON payload:

Parameter Description
id An identity, which is not used for determining who this user is within Quaderno. The id field should therefore not be used for submitting data within Quaderno's API.
name The user's full name.
email The user's email address.
publishable_key The users's publishable key (to use on frontend development).
href The custom API endpoint URL for the user, providing the sought-after ACCOUNT_NAME between https:// and .quadernoapp....

So, this curl call:

curl https://quadernoapp.com/api/authorization \
  -u <YOUR_API_KEY>:x

Returns JSON structured like this:

{
  "identity": {
    "id": "999",
    "name": "Sheldon Cooper",
    "email": "s.cooperphd@yahoo.com",
    "publishable_key":"pk_1111111111111111",
    "href": "https://nippur-999.quadernoapp.com/api/"
  }
}

Note that in all cases, if the user does not have permission to do something, you'll get a 401 Unauthorized error.

Rate Limiting

To make it easier to determine if your application is being rate-limited, or is approaching that level, we have the following HTTP headers on our successful responses:

  • X-RateLimit-Reset: The remaining window before the rate limit resets in UTC epoch seconds.
  • X-RateLimit-Remaining: The number of requests left for the time window.
  • X-RateLimit-Limit: Request limit per time window.

The current limits are 100 API calls per 15 seconds.

We reserve the right to tune the limitations, but we promise to keep them high enough to allow a well-behaving interactive app to do it's job.

When you exceed the limit you will receive a HTTP 429 (Too Many Requests).

Pagination

Pagination is performed with a created_before parameter. This parameter takes an existing object ID value and returns objects listed after the named object, in reverse chronological order.

The HTTP header X-Pages-HasMore indicates whether more records can be fetched by using the same query with a lower created_before.

The HTTP header X-Pages-NextPage contains the URL that should be used to fetch the next page of records. It is only present if more records exist.

Bear in mind that Quaderno paginates GET index results.

You can change the number of objects to be returned with the limit parameter, defaulting to 25. This value is capped at 100 objects.

Example of API call with the created_before parameter set:

curl https://ACCOUNT_NAME.quadernoapp.com/api/contacts?created_before=42 \
  -u <YOUR_API_KEY>:x

Errors

We don't usually have any trouble on our end, but when we do we'll let you know!

The Quaderno API uses the following error codes:

Code Text Description
400 Bad Request Your request may be malformed
401 Unauthorized Your API key is wrong, or your user does not have access to this resource
403 Forbidden The record requested is hidden for administrators only
404 Not Found The specified record could not be found
405 Method Not Allowed You tried to access a record with an invalid method
406 Not Acceptable You requested a format that isn't JSON
410 Gone The record requested has been removed from our servers
422 Unprocessable Entity The requested method cannot process for the record in question
429 Too Many Requests You're requesting too many records! Slow down!
500 Internal Server Error We had a problem with our server. Try again later.
502 Bad Gateway We had a different problem with our server. Try again later.
503 Service Unavailable We're temporarily offline for maintenance, or you've exceeded the rate limit. Please try again later.
504 Gateway Timeout Yep, you guessed it. We'll be back soon!

Note that when API errors occur, it is up to you to retry your request - Quaderno does not keep track of failed calls.

Versioning

The Quaderno API is versioned. Our API versions are named for the date the version is released, like 20220325.

A new API version is released when we introduce a backwards-incompatible change to the API. For example, changing a field type or name, or deprecating endpoints.

The worldwide tax panorama changes fast, and so we adapt. While we're adding functionality to our API, we won't release a new API version. You'll be able to take advantage of this non-breaking backwards-compatible changes directly on the API version you're currently using.

Quaderno considers the following changes to be backwards-compatible:

  • Adding new API resources.
  • Adding new optional request parameters to existing API methods.
  • Adding new properties to existing API responses.
  • Changing the order of properties in existing API responses.
  • Changing the length or format of opaque strings, such as object IDs, error messages, and other human-readable strings.
  • Adding new event types.

Your integration should gracefully handle backwards-compatible changes.

Backwards-incompatible (also called breaking changes) example:

// Prior to version 20210316 the tax calculation endpoint was called like:
/taxes/calculate?country=US&postal_code=94010

// From version 20210316 taxes are calculated with:
/tax_rates/calculate?to_country=US&to_postal_code=90210&tax_code=standard&amount=10

Upgrading your API version

Make sure you upgrade to the latest API version to take advantage of new functionality and streamlined responses. All changes are published on the API Changelog.

Upgrading to an API version with breaking changes might break your current integration, so we recommend testing on Quaderno Sandbox first.

To make the API upgrade definitive or see what version you’re running, visit your Profile → API Keys.

You can also programatically override the account's default API version with an Accept: api_version=version_number header:

curl https://ACCOUNT_NAME.quadernoapp.com/api/contacts.json?created_before=2048 \
  -u <YOUR_API_KEY>:x \
  -H 'Accept: application/json; api_version=20160602'

Version sunsetting and backported changes

From time to time, we will sunset old API versions. All Quaderno accounts using that version will be notified with at least one month in advance. Our own Engineering team will provide full support during transition.

Exceptionally, we might be forced to backport backwards-incompatible changes to all API versions for legal or security reasons, as well as for hotfixes needed to adapt to 3rd parties changes. This is the case of the removal of the DELETE /invoices/INVOICE_ID endpoint during 2021 summer. These changes receive the same treatment as sunsetting API versions.

Stay informed

To get important announcements regarding version sunsetting, backported changes, and new API versions, please ask you account admin to add a developer role with a valid email to their account, so that our API announcements reach its audience.

For being informed of new features and improvements added to the app you can also check quaderno.io/blog/changelog.

Safely upgrading to API version 20220325

In order to avoid manually comparing the explanations of the notice field in the /tax_rates/calculate response, we've revamped the endpoint's reponse to get the calculation reasoning as a status code:

  • taxable: the transaction is taxable and the calculator will return a non-zero rate.
  • non_taxable: The transaction is non taxable if either the particular product is not taxable (ie. a digital product in California) or if the region for a particular territory within the registred jurisdiction is exempted (for example if you're registered in France selling to a customer from New Caledonia)
  • not_registered: You're trying to calculate taxes in a jurisdiction you're not registered in.
  • reverse_charge: The transaction is reverse charge so VAT won't be calculated

In case you were using the notice response field in your API automations, you'll need to swap to the status field, as notice is no longer returned.

Safely upgrading to API version 20210701

In our goal to make Quaderno compliant with tax rules worldwide, we limited the edition of invoices and credit notes via API as of 1st July, 2021.

From that date, an invoice is final (not editable) when any of the following occur:

  • The invoice has been sent to the customer. All sent invoices are final and cannot be edited.
  • The invoice has been paid. All paid invoices are final and cannot be edited.
  • The invoice has been manually marked as final in the dashboard.

If you need to make any changes to invoice's items, taxes, issue date or tax ID, you'll need to issue a credit note and create a new invoice.

You will still be allowed to edit the customer's billing address, PO number, tags, payment details, additional notes, and custom metadata.

What this breaking change implies:

  • DELETE /invoices/INVOICE_ID will cease to exist and return a 410 Gone.
  • PUT /invoices/INVOICE_ID will only allow modification of the parameters po_number, tag_list, payment_details, notes, custom_metadata and all those related to the billing address: street_line_1,street_line_2,city,region,and postal_code.

Note that on 1 July the transition period for 20210316 ends as well, and the legacy endpoints for taxes and pagination will also respond 410 Gone.

If you're using these endpoints, you'll have to include extra logic in your code to issue a credit note and create a new invoice.

However, given your use case is one that automatically issues paid invoices (for instance, your customer's pays and then your system issues the invoice, not the other way around) and you're up for a challenge, our recommendation to face this change is to migrate to the Transactions API.

Why? Because you can create the contact (if doesn't exists yet), create the invoice, and insert the payment information, all in only one performant API call 🎉!

Safely upgrading to API version 20210316

Most changes simply add functionality, thus maintaining backwards compatibility. Occasionally, we release a version with breaking changes, such as 20210316.

Do not fret, the transition to 20210316 is as easy as pie 🥧.

Example of the new Tax Rates endpoint:

curl https://ACCOUNT_NAME.quadernoapp.com/api/tax_rates/calculate?to_country=US&to_postal_code=90210&tax_code=standard&amount=10 \
  -u <YOUR_API_KEY>:x

For calculating tax rates, altough the new endpoint accepts many more parameters, just changing the URL from /taxes/calculate to /tax_rates/calculate will do. Well, not so fast. It may seem it worked quickly, but you're probably getting a 0% tax rate. That's because now you can only collect taxes on Tax Jurisdictions where you're registered. So don't be tempted to create a new custom Tax Rate, just head to your Quaderno Account and update the tax jurisdictions where your business is registered in. Now we're talking! Quaderno will always provide updated worldwide tax rates seamlessly for you.

For paginating objects, we switched to a faster cursor based pagination approach and you'll need to change the page parameter for created_before, which references the ID of the object instead of the page number. You'll get a maximum of 100 objects in reverse chronological order (lower IDs means older objects). Note the response headers changed from X-Pages-CurrentPage and X-Pages-TotalPages to X-Pages-HasMore and X-Pages-NextPage.

You can test all this changes in our Sandbox. There are two approaches:

  • Simply change the API version globally in Profile → API Keys. Note once you change it you cannot change it back, but you can override a concrete call sending the Accept HTTP header with: Accept: application/json; api_version=20170914
  • Sending the Accept HTTP header with: Accept: application/json; api_version=20210316 on every call.

And that's basically it 🎉! Now you can go focus on your business while we deal with your taxes.

Changelog

20241028

  • We now return a 406 Not Acceptable HTTP response when the tax_code in the tax object on any item of the Transactions API is not valid. Valid values, humanized names and explanations can be obtained via the /tax_codes endpoint. Before this API version, any invalid value would be ignored and the account's default would be applied.
  • Fixes a bug where the country param from the tax object on any item of the Transactions API was not required, even if it was documented as so.

20240705

  • Pagination is now sorted by descending ID. This ensures the last item on each page matches the X-Pages-NextPage header, clarifying navigation without changing existing functionalities.
  • Added the ability to set and read the permanent_establishment and import_scheme values when dealing with your business's registered jurisdictions on the /tax_ids endpoints. This change has been backported to all API versions.
  • Information regarding invoices and credits deliveries to external systems like TicketBAI is now accessible via the deliveries object. You can learn more with our TicketBAI guide.

20231201

  • From API version 20231201 onwards, the Transactions API will automatically dispatch invoices and credit notes if the option "Autosend all automatic invoices and credit notes" is selected in your account settings.
  • The long-time deprecated /taxes/validate has been finally removed in favor of /tax_ids/validate. If you were still using it, just make sure your URLs are updated, and that you are sending the tax_id parameter (and not the old vat_number parameter).

Please consider upgrading your API version.

20220325

  • Backwards-compatible change: API listing endpoints /invoices, /credits and /contacts now accept processor_id as filter parameter.
  • Backwards-compatible change: Transactions API now returns the exchange_rate used when the transaction currency differs from the account's default currency.
  • Backwards-compatible change: Billing API now accepts items and evidence objects as Transactions API does. Arrays of items_attributes and evidence_attributes are deprecated but still work.
  • Backwards-compatible change: Expenses API now returns processor and processor_id on the payments objects of payed expenses.
  • Breaking change: /tax_rates/calculate no longer returns a notice explanation text with the tax calculation reason.
  • Backwards-compatible change: /tax_rates/calculate now always show a status on the response indicating a code for the calculation scenario.
  • Backwards-compatible change: Added recurring_period and recurring_frequency to recurring documents.
  • Backwards-compatible change: Added postal_code and web to accounts.

20210701

  • Backwards-compatible change: Added verification_code and verification_permalink to invoices and credits.
  • Backported breaking change: Maximum items per document are now limited up to 200. Before, this was a soft limit per API request, which could be workarounded with subsequent PUT calls.
  • Backwards-compatible change: Billing API now supports partial refunds with the parameter credited_amount for invoices with one single item.
  • Backwards-compatible change: passing none as the region parameter to the GET /jurisdictions endpoint returns jurisdictions that do not have a specific region.
  • Backwards-compatible change: new threshold.eu.100k webhook for the Annual turnover report, to warn whenever sales of digital services within the EU (exclusive of VAT) reach €100,000. Applies only to EU-based sellers.
  • Backported breaking change: abandoned checkout sessions are automatically removed after seven days of inactivity (this is, no updates or not submission attempts from the customer).
  • Backwards-compatible change: we're adding new webhooks for the new Annual turnover report: threshold.warning and threshold.exceeded.
  • Backported breaking change: we're removing the ability to edit coupons linked to Stripe coupons, as they won't allow edition and led to inconsistent states.
  • Backported breaking change: to comply with tax rules worldwide, DELETE /invoices/INVOICE_ID and DELETE /credits/CREDIT_ID endpoints no longer exists and return 404 Not Found. Instead deleting invoices you should associate them to credit notes using POST /credits with the invoice id, which will change its state to paid instead the refunded state. To correct errors creating credits we also provide a PUT /credits/CREDIT_ID/void to void credit notes. Note the webhooks invoice.deleted and credit.deleted are also gone.
  • Backported breaking change: to comply with tax rules worldwide, PUT /invoices/INVOICE_ID and PUT /credits/CREDIT_ID only allow modification of the parameters notes, tag_list, custom_metadata and all those related to the customer's address: street_line_1,street_line_2,city,region,postal_code and country. This change applies to ALL versions.
  • Backwards-compatible change: /tax_rates/calculate now always show a product_type on the response. When you specified the product_type explicitly on the request, we've been showing it in the response. However when you didn't, we used the account's default for tax calculation, and did not return that field. Now we always return the field used for the tax calculation in the response, whether you made it explicit on the request, or the account's default is used. It's a more consistent and informative behaviour.
  • Backwards-compatible change: creating and updating Connect custom accounts (POST and PUT to /accounts endpoint) now accepts specifying the default_product_type and default_tax_code. Before, defaults of service and eservice were applied.

20210316

  • Breaking change: record pagination is no longer performed with a page parameter, but with a created_before parameter. See the pagination documentation for more details.
  • Breaking change: the old /taxes/calculate endpoint is deprecated in favour of the /tax_rates/calculate endpoint.
  • Adds a Deprecation: true header (as per draft-ietf-httpapi-deprecation-header-01) to responses using deprecated pagination, with a Link header linking to the updated documentation. After the deprecation dates, those endpoints will return a 410 Gone.

20170914

  • Added the accounts API
  • Added the related_document to the credit object.
  • Added tax_1_transaction_type and tax_2_transaction_type fields to the taxes attributes in the credit object.
  • Added transaction_type fields to the document items attributes in the credit object.
  • Added kind, stripe_plan_id, paypal_interval_unit, paypal_interval_frequency and paypal_interval_duration fields in the item object.
  • Changed number field limit to 20 characters for invoices, credits and estimates.

20170628

  • Return 429 (too many requests) instead of 503 (service unavailable) on rate limits.

20170418

  • Added custom_metadata as an editable field.

20161108

  • country is now returned as an attribute for invoices, expenses, credits and estimates.

20160614

  • Amounts are now returned as cents instead being formatted as amount with currency symbol.
  • Versions are no longer passed as part of the URL, instead they can be passed as an accept header.

20160602

  • First version.
  • Amounts are returned formatted as amount with currency symbol.

Transactions

Create a transaction

Creates a new sale or refund transaction.

Authorizations:
API keyBearer token
Request Body schema: application/json
type
string
Default: "sale"
Enum: "sale" "refund"

The transaction’s type.

currency
string or null

Three-letter ISO currency code, in uppercase. Defaults to the account’s default currency.

custom_metadata
hash or null

Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format. You can have up to 20 keys, with key names up to 40 characters long and values up to 500 characters long.

object (contact)

The data of the customer who paid the transaction. You can reference an existing contact by its id, or pass the json object to create a new contact.

date
string <date>

The transaction’s date. Defaults to today.

required
Array of objects (transaction_item)

The list of individual items that make up the transaction.

object

The mailing address to where the order will be shipped. Use it if the order contains physical goods.

object (evidence)

Evidence of the customer’s location. Highly recommended.

required
object

Detailed information about the transaction payment.

processor
string or null

The name of the platform that processed the transaction. E.g. shopify, woocommerce or any user agent you may want to use to identify yourself… Recommended

processor_id
string or null

The ID of the transaction in the processor. Use the same ID to link sales and refunds for the same operation. Recommended

processor_fee_cents
integer or null

Processor total fee, in cents.

po_number
string or null

The number of the related order. Recommended.

notes
string or null

Optional notes attached to the transaction.

tags
string or null

Tags attached to the transaction, formatted as a string of comma-separated values. Tags are additional short descriptors, commonly used for filtering and searching. Each individual tag is limited to 40 characters in length.

Responses

Request samples

Content type
application/json
{
  • "type": "sale",
  • "currency": "USD",
  • "custom_metadata": "anything_you_want: extra info",
  • "customer": {
    },
  • "date": "2019-08-24",
  • "items": [
    ],
  • "shipping_address": {
    },
  • "evidence": {
    },
  • "payment": {
    },
  • "processor": "my_platform_user_agent",
  • "processor_id": "my_internal_request_id",
  • "processor_fee_cents": 99,
  • "po_number": "po_xxxxxxxx",
  • "notes": "A note.",
  • "tags": "tagA, tagB"
}

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "created_at": "1593260908",
  • "number": "00001",
  • "issue_date": "2020-06-27",
  • "related_document": {
    },
  • "po_number": "999",
  • "due_date": "2020-07-27",
  • "currency": "USD",
  • "tag_list": "consulting, premium",
  • "notes": "string",
  • "contact": {
    },
  • "country": "US",
  • "postal_code": "91104",
  • "region": "CA",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "tax_id": "string",
  • "subject": "string",
  • "deliveries": [
    ],
  • "items": [
    ],
  • "taxes": [
    ],
  • "payments": [
    ],
  • "payment_processor": "stripe",
  • "payment_processor_id": "ch_999999999999",
  • "processor_fee_cents": 99,
  • "custom_metadata": { },
  • "exchange_rate": 0.680309,
  • "subtotal_cents": 9375,
  • "discount_cents": 0,
  • "total_cents": 9375,
  • "state": "outstanding",
}

Contacts

List contacts

Lists contacts, paginated and sorted by creation date (newest first).

Authorizations:
API keyBearer token
query Parameters
q
string

Filters the contact list based on the contact's full name, email or tax id. Case-sensitive.

processor_id
string

Filters the contact list based on its processor_id.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a contact

Creates a new contact, representing a customer or vendor who appears on invoices, credit notes, and expenses.

Authorizations:
API keyBearer token
Request Body schema: application/json
city
string or null

City/District/Suburb/Town/Village.

contact_person
string or null

If the contact is a company, this is its contact person.

country
string

2-letter ISO country code.

department
string or null

If the contact is a company, this is the deparment.

number or null

Default discount for this contact.

email
string or null <email>

The contact's email address

first_name
required
string

The contact's first name. Only if the contact is a person.

full_name
string

The contact's full name.

kind
string
Default: "company"
Enum: "company" "person"

The type of contact.

language
string

The contact's preferred language. 2-letter ISO language code. Should be included in the account's translations list.

last_name
string or null

The contact's last name. Only if the contact is a person.

notes
string or null

Internal notes about the contact.

phone_1
string or null

The contact's phone number.

postal_code
string or null

ZIP or postal code.

processor
string or null

The external platform where the contact was imported from, if applicable.

processor_id
string or null

The ID the payment_processor assigned to the contact.

region
string or null

State/Province/Region.

street_line_1
string or null

Address line 1 (Street address/PO Box).

street_line_2
string or null

Address line 2 (Apartment/Suite/Unit/Building).

tax_id
string or null

The contact's tax identification number. Quaderno can validate EU VAT numbers, ABN, and NZBN.

tax_status
string
Default: "taxable"
Enum: "taxable" "exempt" "reverse"

Specifies the tax status of the contact.

web
string or null <uri>

The contact's website

Responses

Request samples

Content type
application/json
{
  • "city": "Pasadena",
  • "contact_person": "string",
  • "country": "US",
  • "department": "string",
  • "discount": 0,
  • "email": "leonard@gmail.com",
  • "first_name": "Leonard",
  • "full_name": "Leonard Hofstadter",
  • "kind": "person",
  • "language": "EN",
  • "last_name": "Hofstadter",
  • "notes": "Some private notes about the contact.",
  • "phone_1": "202-555-0104",
  • "postal_code": "91104",
  • "processor": "stripe",
  • "processor_id": "cus_999999999999",
  • "region": "CA",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "tax_id": "string",
  • "tax_status": "taxable",
}

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "city": "Pasadena",
  • "contact_person": "string",
  • "country": "US",
  • "created_at": 1648037653,
  • "department": "string",
  • "discount": 0,
  • "email": "leonard@gmail.com",
  • "first_name": "Leonard",
  • "full_name": "Leonard Hofstadter",
  • "kind": "person",
  • "language": "EN",
  • "last_name": "Hofstadter",
  • "notes": "Some private notes about the contact.",
  • "phone_1": "202-555-0104",
  • "postal_code": "91104",
  • "processor": "stripe",
  • "processor_id": "cus_999999999999",
  • "region": "CA",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "tax_id": "string",
  • "tax_status": "taxable",
}

Retrieve a contact

Retrieves the details of an existing contact.

Authorizations:
API keyBearer token
path Parameters
id
required
string

ID of the desired contact.

Responses

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "city": "Pasadena",
  • "contact_person": "string",
  • "country": "US",
  • "created_at": 1648037653,
  • "department": "string",
  • "discount": 0,
  • "email": "leonard@gmail.com",
  • "first_name": "Leonard",
  • "full_name": "Leonard Hofstadter",
  • "kind": "person",
  • "language": "EN",
  • "last_name": "Hofstadter",
  • "notes": "Some private notes about the contact.",
  • "phone_1": "202-555-0104",
  • "postal_code": "91104",
  • "processor": "stripe",
  • "processor_id": "cus_999999999999",
  • "region": "CA",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "tax_id": "string",
  • "tax_status": "taxable",
}

Update a contact

Updates a contact. Any parameters not provided will be left unchanged.

Authorizations:
API keyBearer token
path Parameters
id
required
integer

ID of the contact to be updated.

Request Body schema: application/json
city
string or null

City/District/Suburb/Town/Village.

contact_person
string or null

If the contact is a company, this is its contact person.

country
string

2-letter ISO country code.

department
string or null

If the contact is a company, this is the deparment.

number or null

Default discount for this contact.

email
string or null <email>

The contact's email address

first_name
required
string

The contact's first name. Only if the contact is a person.

full_name
string

The contact's full name.

kind
string
Default: "company"
Enum: "company" "person"

The type of contact.

language
string

The contact's preferred language. 2-letter ISO language code. Should be included in the account's translations list.

last_name
string or null

The contact's last name. Only if the contact is a person.

notes
string or null

Internal notes about the contact.

phone_1
string or null

The contact's phone number.

postal_code
string or null

ZIP or postal code.

processor
string or null

The external platform where the contact was imported from, if applicable.

processor_id
string or null

The ID the payment_processor assigned to the contact.

region
string or null

State/Province/Region.

street_line_1
string or null

Address line 1 (Street address/PO Box).

street_line_2
string or null

Address line 2 (Apartment/Suite/Unit/Building).

tax_id
string or null

The contact's tax identification number. Quaderno can validate EU VAT numbers, ABN, and NZBN.

tax_status
string
Default: "taxable"
Enum: "taxable" "exempt" "reverse"

Specifies the tax status of the contact.

web
string or null <uri>

The contact's website

Responses

Request samples

Content type
application/json
{
  • "city": "Pasadena",
  • "contact_person": "string",
  • "country": "US",
  • "department": "string",
  • "discount": 0,
  • "email": "leonard@gmail.com",
  • "first_name": "Leonard",
  • "full_name": "Leonard Hofstadter",
  • "kind": "person",
  • "language": "EN",
  • "last_name": "Hofstadter",
  • "notes": "Some private notes about the contact.",
  • "phone_1": "202-555-0104",
  • "postal_code": "91104",
  • "processor": "stripe",
  • "processor_id": "cus_999999999999",
  • "region": "CA",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "tax_id": "string",
  • "tax_status": "taxable",
}

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "city": "Pasadena",
  • "contact_person": "string",
  • "country": "US",
  • "created_at": 1648037653,
  • "department": "string",
  • "discount": 0,
  • "email": "leonard@gmail.com",
  • "first_name": "Leonard",
  • "full_name": "Leonard Hofstadter",
  • "kind": "person",
  • "language": "EN",
  • "last_name": "Hofstadter",
  • "notes": "Some private notes about the contact.",
  • "phone_1": "202-555-0104",
  • "postal_code": "91104",
  • "processor": "stripe",
  • "processor_id": "cus_999999999999",
  • "region": "CA",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "tax_id": "string",
  • "tax_status": "taxable",
}

Delete a contact

Permanently deletes a contact. This action cannot be undone.

Authorizations:
API keyBearer token
path Parameters
id
required
string

ID of the contact to be deleted.

Responses

Products

List products

Lists all products, paginated and sorted by creation date (newest first).

Authorizations:
API keyBearer token
query Parameters
q
string

Filters a product list based on the product's name or code. Case-sensitive.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a product

Creates a new product, which could be used as line item on invoices, credit notes and expenses.

Authorizations:
API keyBearer token
Request Body schema: application/json
code
required
string

The product’s SKU (Stock Keeping Unit) describe specific product variations, taking into account any combination of: attributes, currency, and cost.

country
string or null

2-letter ISO country code. Required if tax_based_on is country.

currency
string or null

Three-letter ISO currency code, in uppercase. Must be a supported currency in your payment processors.

description
required
string or null

The product’s description, meant to be displayable to the customer. Use this field to optionally store a long form explanation of the product being sold for your own rendering purposes.

paypal_interval_duration
integer or null

Only for subscriptions. Number of times the charge should recur.

paypal_interval_frequency
integer or null

Only for PayPal subscriptions. The number of intervals between subscription billings.

paypal_interval_unit
string
Default: "monthly"
Enum: "daily" "weekly" "monthly" "yearly"

Only for PayPal subscriptions. Specifies billing frequency.

kind
required
string
Default: "one_off"
Enum: "one_off" "subscription"

The type of transaction: one-off purchase or subscription.

name
required
string

The product’s name, meant to be displayable to the customer.

product_type
required
string
Default: "service"
Enum: "good" "service"

The type of the product. The product is either a tangible good or a service.

stripe_plan_id
string or null

Only for Stripe subscriptions. ID of the Stripe price related to the subscription.

tax_based_on
required
string
Default: "customer_country"
Enum: "customer_country" "country"

How taxes are going to be calculated: based on the customer country or a particular country.

tax_class
required
string
Default: "eservice"
Enum: "consulting" "eservice" "ebook" "saas" "standard" "reduced"

The tax class that applies to the product.

tax_type
required
string
Default: "included"
Enum: "excluded" "included"

Specify if taxes are included or excluded in the unit_cost.

unit_cost
required
string

The unit amount to be charged

stock
required
string or null

The stock of the physical product.

Responses

Request samples

Content type
application/json
{
  • "code": "012345678901-MFN",
  • "country": "US",
  • "currency": "USD",
  • "description": "string",
  • "paypal_interval_duration": 1,
  • "paypal_interval_frequency": 0,
  • "paypal_interval_unit": "monthly",
  • "kind": "one_off",
  • "name": "Ruby Essentials",
  • "product_type": "good",
  • "stripe_plan_id": "price_1GtYUvKYlo3Dy5yXgrQS",
  • "tax_based_on": "customer_country",
  • "tax_class": "consulting",
  • "tax_type": "excluded",
  • "unit_cost": "9.99",
  • "stock": "10"
}

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "code": "012345678901-MFN",
  • "country": "US",
  • "created_at": "1593260908",
  • "currency": "USD",
  • "description": "string",
  • "paypal_interval_duration": 1,
  • "paypal_interval_frequency": 0,
  • "paypal_interval_unit": "monthly",
  • "kind": "one_off",
  • "name": "Ruby Essentials",
  • "product_type": "good",
  • "stripe_plan_id": "price_1GtYUvKYlo3Dy5yXgrQS",
  • "tax_based_on": "customer_country",
  • "tax_class": "consulting",
  • "tax_type": "excluded",
  • "unit_cost": "9.99",
  • "stock": "10"
}

Retrieve a product

Retrieves the details of an existing product.

Authorizations:
API keyBearer token
path Parameters
id
required
string

ID of the desired product.

Responses

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "code": "012345678901-MFN",
  • "country": "US",
  • "created_at": "1593260908",
  • "currency": "USD",
  • "description": "string",
  • "paypal_interval_duration": 1,
  • "paypal_interval_frequency": 0,
  • "paypal_interval_unit": "monthly",
  • "kind": "one_off",
  • "name": "Ruby Essentials",
  • "product_type": "good",
  • "stripe_plan_id": "price_1GtYUvKYlo3Dy5yXgrQS",
  • "tax_based_on": "customer_country",
  • "tax_class": "consulting",
  • "tax_type": "excluded",
  • "unit_cost": "9.99",
  • "stock": "10"
}

Update a product

Updates a product. Any parameters not provided will be left unchanged.

Authorizations:
API keyBearer token
path Parameters
id
required
integer

ID of the product to be updated.

Request Body schema: application/json
code
required
string

The product’s SKU (Stock Keeping Unit) describe specific product variations, taking into account any combination of: attributes, currency, and cost.

country
string or null

2-letter ISO country code. Required if tax_based_on is country.

currency
string or null

Three-letter ISO currency code, in uppercase. Must be a supported currency in your payment processors.

description
required
string or null

The product’s description, meant to be displayable to the customer. Use this field to optionally store a long form explanation of the product being sold for your own rendering purposes.

paypal_interval_duration
integer or null

Only for subscriptions. Number of times the charge should recur.

paypal_interval_frequency
integer or null

Only for PayPal subscriptions. The number of intervals between subscription billings.

paypal_interval_unit
string
Default: "monthly"
Enum: "daily" "weekly" "monthly" "yearly"

Only for PayPal subscriptions. Specifies billing frequency.

kind
required
string
Default: "one_off"
Enum: "one_off" "subscription"

The type of transaction: one-off purchase or subscription.

name
required
string

The product’s name, meant to be displayable to the customer.

product_type
required
string
Default: "service"
Enum: "good" "service"

The type of the product. The product is either a tangible good or a service.

stripe_plan_id
string or null

Only for Stripe subscriptions. ID of the Stripe price related to the subscription.

tax_based_on
required
string
Default: "customer_country"
Enum: "customer_country" "country"

How taxes are going to be calculated: based on the customer country or a particular country.

tax_class
required
string
Default: "eservice"
Enum: "consulting" "eservice" "ebook" "saas" "standard" "reduced"

The tax class that applies to the product.

tax_type
required
string
Default: "included"
Enum: "excluded" "included"

Specify if taxes are included or excluded in the unit_cost.

unit_cost
required
string

The unit amount to be charged

stock
required
string or null

The stock of the physical product.

Responses

Request samples

Content type
application/json
{
  • "code": "012345678901-MFN",
  • "country": "US",
  • "currency": "USD",
  • "description": "string",
  • "paypal_interval_duration": 1,
  • "paypal_interval_frequency": 0,
  • "paypal_interval_unit": "monthly",
  • "kind": "one_off",
  • "name": "Ruby Essentials",
  • "product_type": "good",
  • "stripe_plan_id": "price_1GtYUvKYlo3Dy5yXgrQS",
  • "tax_based_on": "customer_country",
  • "tax_class": "consulting",
  • "tax_type": "excluded",
  • "unit_cost": "9.99",
  • "stock": "10"
}

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "code": "012345678901-MFN",
  • "country": "US",
  • "created_at": "1593260908",
  • "currency": "USD",
  • "description": "string",
  • "paypal_interval_duration": 1,
  • "paypal_interval_frequency": 0,
  • "paypal_interval_unit": "monthly",
  • "kind": "one_off",
  • "name": "Ruby Essentials",
  • "product_type": "good",
  • "stripe_plan_id": "price_1GtYUvKYlo3Dy5yXgrQS",
  • "tax_based_on": "customer_country",
  • "tax_class": "consulting",
  • "tax_type": "excluded",
  • "unit_cost": "9.99",
  • "stock": "10"
}

Delete a product

Permanently deletes a product. This action cannot be undone.

Authorizations:
API keyBearer token
path Parameters
id
required
string

ID of the product to be deleted.

Responses

Tax Rates

Calculate a tax rate

Calculates the applicable tax rate for a given address and transaction type.

Authorizations:
API keyBearer token
query Parameters
from_country
string

The seller's country. 2-letter ISO country code. Defaults to the account's country.

from_postal_code
string

The seller's ZIP or postal code. Defaults to the account's postal code.

to_country
required
string
Example: to_country=US

The customer's country. 2-letter ISO country code.

to_postal_code
string
Example: to_postal_code=10128

The customer's ZIP or postal code.

to_city
string
Example: to_city=New York

The customer's city. Only for US sales tax.

tax_id
string

The customer's tax ID. Quaderno can validate VAT/GST numbers from the EU, United Kingdom, Switzerland, Québec (Canada), Australia, and New Zealand.

tax_code
string
Enum: "consulting" "eservice" "ebook" "saas" "standard" "reduced" "exempt"
Example: tax_code=eservice

The transaction's tax code. Tax codes can be obtained via GET /tax_codes. Defaults to the account's default tax code.

tax_behavior
string
Enum: "inclusive" "exclusive"

Specifies whether the price is considered inclusive of taxes or exclusive of taxes.

product_type
string
Enum: "good" "service"

Specifies whether the product is a good or a service. Defaults to the account's default.

date
string

The transaction's date. Defaults to today.

amount
string

The transaction's amount.

currency
string

The transaction's currency. Three-letter ISO currency code, in uppercase. Defaults to the account's currency.

Responses

Response samples

Content type
application/json
{
  • "name": "Sales tax",
  • "rate": 8.875,
  • "taxable_part": 100,
  • "country": "US",
  • "region": "NY",
  • "county": "NEW YORK",
  • "city": "NEW YORK",
  • "tax_code": "eservice",
  • "tax_behavior": "eservice",
  • "tax_amount": 100,
  • "subtotal": 100,
  • "total_amount": 100,
  • "status": "not_registered",
  • "notes": "Tax amount subject to reverse charge.",
  • "notice": "You aren't registered for tax collection in United States - New York. If you need to collect taxes there, please add the tax jurisdiction to your Quaderno account.",
  • "additional_name": "string",
  • "additional_rate": 0.1,
  • "additional_taxable_part": 0.1,
  • "additional_tax_amount": 0.1
}

Tax IDs

Validate a tax id

The result can be true (valid tax ID, meaning it represents a business), false (invalid tax ID) or null (the external validation service is temporarily unavailable).

Authorizations:
API keyBearer token
query Parameters
country
required
string
Example: country=DE

Tax ID's registration country, represented as 2-letter ISO 3166-1 code.

tax_id
string
Example: tax_id=DE303954554

The tax ID to be validated.

Responses

Response samples

Content type
application/json
{
  • "valid": true
}

Tax Jurisdictions

Retrieve a jurisdiction

Retrieves a tax jurisdiction (area subject to its own tax regulations).

Authorizations:
API keyBearer token
path Parameters
id
required
string

ID of the desired jurisdiction.

Responses

Response samples

Content type
application/json
{
  • "id": 94,
  • "name": "Canada - British Columbia",
  • "country": "CA",
  • "region": "BC"
}

List all jurisdiction

Retrieves the list of all tax jurisdictions (areas subject to its own tax regulations).

Authorizations:
API keyBearer token
query Parameters
country
string
Example: country=CA

Case-sensitive filter based on the jurisdiction's country 2-letter ISO 3166-1 code.

region
string

Case-sensitive filter based on the jurisdiction's region. Accepts the special string none to return jurisdictions that specifically have no region.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Registered Jurisdictions

Registered jurisdictions refer to the locations where your business is registered to collect taxes and has a local tax id. This registration is independent of the countries or states where you sell your products or services.

List tax IDs

Lists all registered tax IDs.

Authorizations:
API keyBearer token

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a tax ID

Registers a new tax ID representing a business and associates it to a specific tax jurisdiction.

Authorizations:
API keyBearer token
Request Body schema: application/json
jurisdiction_id
required
integer

ID of the tax jurisdiction where the tax ID is registered.

value
required
string

Value of the tax ID. For instance, a VAT number.

valid_from
string

The tax ID's validity date. Defaults to the beginning of the year.

valid_until
string

The tax ID's expiration date, or null if the tax ID has no expiration date.

permanent_establishment
boolean
Default: false

Whether your business has physical presence (office, warehouse, etc) in the given jurisdiction.

import_scheme
boolean
Default: false

Whether the business is registered or not in the EU import scheme for foreign sellers of physical goods.

Responses

Request samples

Content type
application/json
{
  • "jurisdiction_id": 94,
  • "value": "123456789BW0001",
  • "valid_from": "2023-01-01",
  • "valid_until": "",
  • "permanent_establishment": true,
  • "import_scheme": true
}

Response samples

Content type
application/json
{
  • "id": 23546,
  • "import_scheme": true,
  • "jurisdiction": {
    },
  • "permanent_establishment": true,
  • "state": "verified",
  • "valid_from": "2023-01-01",
  • "valid_until": "2024-12-31",
  • "value": "123456789BW0001",
  • "created_at": 1681199310
}

Retrieve a tax ID

Retrieves the details of an existing tax ID.

Authorizations:
API keyBearer token
path Parameters
id
required
integer

ID of the desired tax ID.

Responses

Response samples

Content type
application/json
{
  • "id": 23546,
  • "import_scheme": true,
  • "jurisdiction": {
    },
  • "permanent_establishment": true,
  • "state": "verified",
  • "valid_from": "2023-01-01",
  • "valid_until": "2024-12-31",
  • "value": "123456789BW0001",
  • "created_at": 1681199310
}

Update a tax ID

Updates a tax ID. Any parameters not provided will be left unchanged.

Authorizations:
API keyBearer token
path Parameters
id
required
any

ID of the tax ID to be updated.

Request Body schema: application/json
value
string

Value of the tax ID you need fixing.

valid_from
string

The tax ID's validity date. Defaults to the beginning of the year.

valid_until
string

The tax ID's expiration date, or null if the tax ID has no expiration date.

permanent_establishment
boolean
Default: false

Whether your business has physical presence (office, warehouse, etc) in the given jurisdiction.

import_scheme
boolean
Default: false

Whether the business is registered or not in the EU import scheme for foreign sellers of physical goods.

Responses

Request samples

Content type
application/json
{
  • "value": "123456789BW0001",
  • "valid_from": "2023-01-01",
  • "valid_until": "2024-12-31",
  • "permanent_establishment": true,
  • "import_scheme": true
}

Response samples

Content type
application/json
{
  • "id": 23546,
  • "import_scheme": true,
  • "jurisdiction": {
    },
  • "permanent_establishment": true,
  • "state": "verified",
  • "valid_from": "2023-01-01",
  • "valid_until": "2024-12-31",
  • "value": "123456789BW0001",
  • "created_at": 1681199310
}

Delete a tax ID

Permanently deletes a tax ID. This action cannot be undone.

Authorizations:
API keyBearer token
path Parameters
id
required
string

ID of the tax ID to be deleted.

Responses

Tax Codes

Retrieve a tax code

Retrieves a tax code, which classify goods and services for tax purposes.

Authorizations:
API keyBearer token
path Parameters
id
required
string
Enum: "consulting" "ebook" "eservice" "exempt" "reduced" "saas" "standard"
Example: eservice

The ID of the tax code to retrieve.

Responses

Response samples

Content type
application/json
{
  • "id": "eservice",
  • "description": "Service that is delivered over the internet. It is essentially automated, involves minimal human intervention and in the absence of information technology does not have viability.",
  • "name": "Electronically supplied services"
}

List all tax codes

Retrieves the list of supported tax codes.

Authorizations:
API keyBearer token

Responses

Response samples

Content type
application/json
[
  • {
    },
  • {
    },
  • {
    },
  • {
    },
  • {
    },
  • {
    },
  • {
    }
]

Evidence

List all evidence objects

Retrieves the list of evidence objects, paginated and sorted by creation date (newest first).

Authorizations:
API keyBearer token
query Parameters
state
string

A filter on the list based on the evidence's state. You can combine multiple states separated by commas. Valid states are confirmed, unsettled, and conflicting.

document_id
integer

A filter on the list based on the evidence's related document.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create an evidence

Creates a new evidence.

Authorizations:
API keyBearer token
Request Body schema: application/json
additional_evidence
string or null

Additional evidence used to proof the customer's location. Required if there's a `additional_evidence_country'.

additional_evidence_country
string or null

2-letter ISO 3166-1 code.

bank_country
string or null

2-letter ISO 3166-1 code.

billing_country
string or null

2-letter ISO 3166-1 code.

document_id
required
integer

Unique identifier for the related invoice.

ip_address
string or null

The customer's IP address

notes
string or null

Internal notes about the evidence.

state
string
Default: "unsettled"
Enum: "unsettled" "conflicting" "confirmed"

State of the evidence

Responses

Request samples

Content type
application/json
{
  • "additional_evidence": "Phone bill",
  • "additional_evidence_country": "DE",
  • "bank_country": "DE",
  • "billing_country": "DE",
  • "document_id": 43123,
  • "ip_address": "127.0.0.1",
  • "notes": "Some private notes about the evidence.",
  • "state": "unsettled"
}

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "additional_evidence": "Phone bill",
  • "additional_evidence_country": "DE",
  • "bank_country": "DE",
  • "billing_country": "DE",
  • "created_at": "1593260908",
  • "document_id": 43123,
  • "ip_address": "127.0.0.1",
  • "ip_country": "DE",
  • "notes": "Some private notes about the evidence.",
  • "state": "unsettled",
}

Retrieve an evidence

Retrieves updated info from the evidence.

Authorizations:
API keyBearer token
path Parameters
id
required
string
Example: 41

The ID of the evidence to retrieve.

Responses

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "additional_evidence": "Phone bill",
  • "additional_evidence_country": "DE",
  • "bank_country": "DE",
  • "billing_country": "DE",
  • "created_at": "1593260908",
  • "document_id": 43123,
  • "ip_address": "127.0.0.1",
  • "ip_country": "DE",
  • "notes": "Some private notes about the evidence.",
  • "state": "unsettled",
}

Update an evidence

Updates the specified evidence by setting the values of the parameters passed. Any parameters not provided will be left unchanged. This request accepts mostly the same arguments as the evidence creation call.

Authorizations:
API keyBearer token
path Parameters
id
required
integer

The ID of the evidence to be updated.

Request Body schema: application/json
additional_evidence
string or null

Additional evidence used to proof the customer's location. Required if there's a `additional_evidence_country'.

additional_evidence_country
string or null

2-letter ISO 3166-1 code.

bank_country
string or null

2-letter ISO 3166-1 code.

billing_country
string or null

2-letter ISO 3166-1 code.

document_id
required
integer

Unique identifier for the related invoice.

ip_address
string or null

The customer's IP address

notes
string or null

Internal notes about the evidence.

state
string
Default: "unsettled"
Enum: "unsettled" "conflicting" "confirmed"

State of the evidence

Responses

Request samples

Content type
application/json
{
  • "additional_evidence": "Phone bill",
  • "additional_evidence_country": "DE",
  • "bank_country": "DE",
  • "billing_country": "DE",
  • "document_id": 43123,
  • "ip_address": "127.0.0.1",
  • "notes": "Some private notes about the evidence.",
  • "state": "unsettled"
}

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "additional_evidence": "Phone bill",
  • "additional_evidence_country": "DE",
  • "bank_country": "DE",
  • "billing_country": "DE",
  • "created_at": "1593260908",
  • "document_id": 43123,
  • "ip_address": "127.0.0.1",
  • "ip_country": "DE",
  • "notes": "Some private notes about the evidence.",
  • "state": "unsettled",
}

Invoices

List all invoices

Lists all invoices, paginated and sorted by creation date (newest first).

Authorizations:
API keyBearer token
query Parameters
q
string

Filters an invoices list based on the invoice number, customer name or PO number.

date
string

Filters an invoices list based on the issue date. A date range must be entered. Allowed formats are 2019-01-01,2019-12-31 and 2019/01/01,2019/12/31.

state
string
Enum: "outstanding" "late" "uncollectible" "paid" "refunded" "archived"

Filters an invoices list based on the invoice state.

processor_id
string

Filters an invoices list based on its processor_id.

contact
integer

Filters an invoices list based on the customer ID.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create an invoice

Creates a new invoice object.

Authorizations:
API keyBearer token
Request Body schema: application/json
number
string

A unique, sequential code that identifies the invoice. Legally, an invoice number sequence should never contain repeats or gaps. Automatic numbering is used by default.

issue_date
string <date>

The date of the invoice’s issue - not necessarily the date the products or services were provided.

po_number
string or null

Purchase order number.

due_date
string or null <date>

The date on which payment for this invoice is due.

currency
string

Three-letter ISO currency code, in uppercase.

recurring_period
string or null
Enum: "days" "weeks" "months" "years"

Recurring period.

recurring_frequency
number or null

Recurring frequency.

tag_list
Array of strings or null

Multiple tags should be separated by commas.

payment_details
string or null

Detailed information about the accepted payment methods.

notes
string or null

Extra notes about the invoice.

required
contact (object) or object

Customer who will be billed.

object (attachment)

Invoices and expenses can have attached files.

street_line_1
string or null

The customer’s billing address line 1 (Street address/PO Box).

street_line_2
string or null

The customer’s billing address line 2 (Apartment/Suite/Unit/Building).

tax_id
string or null

The customer’s tax identification number.

subject
string or null

An optional summary description of the document.

required
Array of objects (document_item)

The individual line items that make up the invoice. No more than 200 items are allowed in a request. To add more use subsequent update requests. Maximum items per document are limited up to 1000 items.

object (evidence)

Location evidence used to calculate the invoice’s tax, if applicable.

payment_processor
string or null

The payment processor used to process the invoice.

payment_processor_id
string or null

The ID the payment_processor assigned to the invoice.

processor_fee_cents
integer or null

Processor total fee, in cents.

custom_metadata
object or null

Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.

Responses

Request samples

Content type
application/json
{
  • "number": "00001",
  • "issue_date": "2020-06-27",
  • "po_number": "999",
  • "due_date": "2020-07-27",
  • "currency": "USD",
  • "recurring_period": "days",
  • "recurring_frequency": 0,
  • "tag_list": "consulting, premium",
  • "payment_details": "string",
  • "notes": "string",
  • "contact": {
    },
  • "attachment": {
    },
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "tax_id": "string",
  • "subject": "string",
  • "items": [
    ],
  • "evidence": {
    },
  • "payment_processor": "stripe",
  • "payment_processor_id": "ch_999999999999",
  • "processor_fee_cents": 99,
  • "custom_metadata": { }
}

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "created_at": 1593260908,
  • "number": "00001",
  • "issue_date": "2020-06-27",
  • "related_document": {
    },
  • "po_number": "999",
  • "due_date": "2020-07-27",
  • "currency": "USD",
  • "recurring_period": "days",
  • "recurring_frequency": 0,
  • "tag_list": "consulting, premium",
  • "payment_details": "string",
  • "notes": "string",
  • "contact": {
    },
  • "country": "US",
  • "postal_code": "91104",
  • "region": "CA",
  • "city": "null",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "tax_id": "string",
  • "subject": "string",
  • "deliveries": [
    ],
  • "items": [
    ],
  • "taxes": [
    ],
  • "payments": [
    ],
  • "evidence": {
    },
  • "payment_processor": "stripe",
  • "payment_processor_id": "ch_999999999999",
  • "processor_fee_cents": 99,
  • "custom_metadata": { },
  • "exchange_rate": 0.680309,
  • "subtotal_cents": 9375,
  • "discount_cents": 0,
  • "total_cents": 9375,
  • "state": "outstanding",
}

Retrieve an invoice

Retrieves the details of an existing invoice. You need only supply the unique invoice identifier that was returned upon invoice creation.

Authorizations:
API keyBearer token
path Parameters
id
required
string

The ID of the desired invoice.

Responses

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "created_at": 1593260908,
  • "number": "00001",
  • "issue_date": "2020-06-27",
  • "related_document": {
    },
  • "po_number": "999",
  • "due_date": "2020-07-27",
  • "currency": "USD",
  • "recurring_period": "days",
  • "recurring_frequency": 0,
  • "tag_list": "consulting, premium",
  • "payment_details": "string",
  • "notes": "string",
  • "contact": {
    },
  • "country": "US",
  • "postal_code": "91104",
  • "region": "CA",
  • "city": "null",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "tax_id": "string",
  • "subject": "string",
  • "deliveries": [
    ],
  • "items": [
    ],
  • "taxes": [
    ],
  • "payments": [
    ],
  • "evidence": {
    },
  • "payment_processor": "stripe",
  • "payment_processor_id": "ch_999999999999",
  • "processor_fee_cents": 99,
  • "custom_metadata": { },
  • "exchange_rate": 0.680309,
  • "subtotal_cents": 9375,
  • "discount_cents": 0,
  • "total_cents": 9375,
  • "state": "outstanding",
}

Update an invoice

To comply with international tax laws, invoices that have already been paid or delivered to the customer cannot be modified except for a few fields. For invoices not paid or delivered, the endpoint accepts all parameters documented in the create endpoint.

Authorizations:
API keyBearer token
path Parameters
id
required
integer

The ID of the invoice to be updated.

Request Body schema: application/json
po_number
string or null

Purchase order number.

tag_list
Array of strings or null

Multiple tags should be separated by commas.

payment_details
string or null

Detailed information about the accepted payment methods.

notes
string or null

Extra notes about the document.

street_line_1
string or null

The customer’s billing address line 1 (Street address/PO Box).

street_line_2
string or null

The customer’s billing address line 2 (Apartment/Suite/Unit/Building).

custom_metadata
object or null

Set of key-value pairs that you can attach to the object. This can be useful for storing additional information about the object in a structured format.

object (attachment)

Invoices and expenses can have attached files.

Responses

Request samples

Content type
application/json
{
  • "po_number": "999",
  • "tag_list": "consulting, premium",
  • "payment_details": "string",
  • "notes": "string",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "custom_metadata": { },
  • "attachment": {
    }
}

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "created_at": 1593260908,
  • "number": "00001",
  • "issue_date": "2020-06-27",
  • "related_document": {
    },
  • "po_number": "999",
  • "due_date": "2020-07-27",
  • "currency": "USD",
  • "recurring_period": "days",
  • "recurring_frequency": 0,
  • "tag_list": "consulting, premium",
  • "payment_details": "string",
  • "notes": "string",
  • "contact": {
    },
  • "country": "US",
  • "postal_code": "91104",
  • "region": "CA",
  • "city": "null",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "tax_id": "string",
  • "subject": "string",
  • "deliveries": [
    ],
  • "items": [
    ],
  • "taxes": [
    ],
  • "payments": [
    ],
  • "evidence": {
    },
  • "payment_processor": "stripe",
  • "payment_processor_id": "ch_999999999999",
  • "processor_fee_cents": 99,
  • "custom_metadata": { },
  • "exchange_rate": 0.680309,
  • "subtotal_cents": 9375,
  • "discount_cents": 0,
  • "total_cents": 9375,
  • "state": "outstanding",
}

Deleting invoices is not allowed

Per tax compliance, invoices cannot be deleted. To cancel out an invoice, please issue a credit note.

Authorizations:
API keyBearer token
path Parameters
id
required
string

The ID of an invoice.

Responses

Deliver an invoice

Delivers an invoice to your customer via email.

Authorizations:
API keyBearer token
path Parameters
id
required
string

The ID of the desired invoice.

Responses

Credits

List all credit notes

Lists all credit notes, paginated and sorted by creation date (newest first).

Authorizations:
API keyBearer token
query Parameters
q
string

Filters a credit notes list based on the credit number, customer name or PO number.

date
string

Filters a credit notes list based on the issue date. A date range must be entered. Allowed formats are 2019-01-01,2019-12-31 and 2019/01/01,2019/12/31.

state
string
Enum: "outstanding" "late" "uncollectible" "paid" "refunded" "archived"

Filters a credit notes list based on the credit state.

processor_id
string

Filters a credit notes list based on its processor_id.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a credit note

Creates a new credit note that cancels out an existing invoice.

Authorizations:
API keyBearer token
Request Body schema: application/json
invoice_id
required
integer

The ID of the refunded invoice.

payment_method
string
Enum: "credit_card" "cash" "wire_transfer" "direct_debit" "check" "iou" "paypal" "other"

Payment method used to refund the credited amount.

credited_amount
number

Total amount to be credited, equal or lower than the total amount of the related invoice. Only works for refunds of invoices with one single item. When empty, defaults to the total amount of the related invoice.

Responses

Request samples

Content type
application/json
Example
{
  • "invoice_id": 139331
}

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "created_at": "1593260908",
  • "number": "00001",
  • "issue_date": "2020-06-27",
  • "related_document": {
    },
  • "po_number": "999",
  • "due_date": "2020-07-27",
  • "currency": "USD",
  • "tag_list": "consulting, premium",
  • "notes": "string",
  • "contact": {
    },
  • "country": "US",
  • "postal_code": "91104",
  • "region": "CA",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "tax_id": "string",
  • "subject": "string",
  • "deliveries": [
    ],
  • "items": [
    ],
  • "taxes": [
    ],
  • "payments": [
    ],
  • "payment_processor": "stripe",
  • "payment_processor_id": "ch_999999999999",
  • "processor_fee_cents": 99,
  • "custom_metadata": { },
  • "exchange_rate": 0.680309,
  • "subtotal_cents": 9375,
  • "discount_cents": 0,
  • "total_cents": 9375,
  • "state": "outstanding",
}

Retrieve a credit note

Retrieves the details of an existing credit note.

Authorizations:
API keyBearer token
path Parameters
id
required
string

The ID of the desired credit.

Responses

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "created_at": "1593260908",
  • "number": "00001",
  • "issue_date": "2020-06-27",
  • "related_document": {
    },
  • "po_number": "999",
  • "due_date": "2020-07-27",
  • "currency": "USD",
  • "tag_list": "consulting, premium",
  • "notes": "string",
  • "contact": {
    },
  • "country": "US",
  • "postal_code": "91104",
  • "region": "CA",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "tax_id": "string",
  • "subject": "string",
  • "deliveries": [
    ],
  • "items": [
    ],
  • "taxes": [
    ],
  • "payments": [
    ],
  • "payment_processor": "stripe",
  • "payment_processor_id": "ch_999999999999",
  • "processor_fee_cents": 99,
  • "custom_metadata": { },
  • "exchange_rate": 0.680309,
  • "subtotal_cents": 9375,
  • "discount_cents": 0,
  • "total_cents": 9375,
  • "state": "outstanding",
}

Update a credit note

To comply with international tax laws, credit notes that have already been paid or delivered to the customer cannot be modified except for a few fields. For credit notes not paid or delivered, the endpoint accepts all parameters documented in the create endpoint.

Authorizations:
API keyBearer token
path Parameters
id
required
integer

The ID of the credit to be updated.

Request Body schema: application/json
po_number
string or null

Purchase order number.

tag_list
Array of strings or null

Multiple tags should be separated by commas.

payment_details
string or null

Detailed information about the accepted payment methods.

notes
string or null

Extra notes about the document.

street_line_1
string or null

The customer’s billing address line 1 (Street address/PO Box).

street_line_2
string or null

The customer’s billing address line 2 (Apartment/Suite/Unit/Building).

custom_metadata
object or null

Set of key-value pairs that you can attach to the object. This can be useful for storing additional information about the object in a structured format.

object (attachment)

Invoices and expenses can have attached files.

Responses

Request samples

Content type
application/json
{
  • "po_number": "999",
  • "tag_list": "consulting, premium",
  • "payment_details": "string",
  • "notes": "string",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "custom_metadata": { },
  • "attachment": {
    }
}

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "created_at": "1593260908",
  • "number": "00001",
  • "issue_date": "2020-06-27",
  • "related_document": {
    },
  • "po_number": "999",
  • "due_date": "2020-07-27",
  • "currency": "USD",
  • "tag_list": "consulting, premium",
  • "notes": "string",
  • "contact": {
    },
  • "country": "US",
  • "postal_code": "91104",
  • "region": "CA",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "tax_id": "string",
  • "subject": "string",
  • "deliveries": [
    ],
  • "items": [
    ],
  • "taxes": [
    ],
  • "payments": [
    ],
  • "payment_processor": "stripe",
  • "payment_processor_id": "ch_999999999999",
  • "processor_fee_cents": 99,
  • "custom_metadata": { },
  • "exchange_rate": 0.680309,
  • "subtotal_cents": 9375,
  • "discount_cents": 0,
  • "total_cents": 9375,
  • "state": "outstanding",
}

Deleting credit notes is not allowed

Per tax compliance, credit notes cannot be deleted. To cancel out a credit, please mark it as void.

Authorizations:
API keyBearer token
path Parameters
id
required
string

The ID of a credit.

Responses

Void a credit note

Voids a credit note, effectively canceling it.

Authorizations:
API keyBearer token
path Parameters
id
required
integer

The ID of the credit to be voided.

Responses

Response samples

Content type
application/json
{
  • "id": 92732431,
  • "created_at": "1593260908",
  • "number": "00001",
  • "issue_date": "2020-06-27",
  • "related_document": {
    },
  • "po_number": "999",
  • "due_date": "2020-07-27",
  • "currency": "USD",
  • "tag_list": "consulting, premium",
  • "notes": "string",
  • "contact": {
    },
  • "country": "US",
  • "postal_code": "91104",
  • "region": "CA",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "tax_id": "string",
  • "subject": "string",
  • "deliveries": [
    ],
  • "items": [
    ],
  • "taxes": [
    ],
  • "payments": [
    ],
  • "payment_processor": "stripe",
  • "payment_processor_id": "ch_999999999999",
  • "processor_fee_cents": 99,
  • "custom_metadata": { },
  • "exchange_rate": 0.680309,
  • "subtotal_cents": 9375,
  • "discount_cents": 0,
  • "total_cents": 9375,
  • "state": "outstanding",
}

Deliver a credit

Delivers a credit to your customer via email.

Authorizations:
API keyBearer token
path Parameters
id
required
string

The ID of the desired credit.

Responses

Expenses

List all expenses

Lists all expenses, paginated and sorted by creation date (newest first).

Authorizations:
API keyBearer token
query Parameters
q
string

Filters an expenses list based on the expense number, customer name or PO number.

date
string

Filters an expenses list based on the issue date. A date range must be entered. Allowed formats are 2019-01-01,2019-12-31 and 2019/01/01,2019/12/31.

state
string
Enum: "outstanding" "late" "paid"

Filters an expenses list based on the expense state: outstanding, late and paid.

contact
integer

Filters an expenses list based on the customer ID.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create an expense

Creates a new expense.

Authorizations:
API keyBearer token
Request Body schema: application/json
issue_date
string <date>

Date when the expense was issued.

po_number
string or null

Purchase order number.

currency
string

Three-letter ISO currency code, in uppercase.

tag_list
Array of strings or null

Multiple tags should be separated by commas.

payment_details
string or null

Detailed information about the payment.

notes
string or null

Extra notes about the expense.

required
contact (object) or object

Provider of your expense.

object (attachment)

Invoices and expenses can have attached files.

country
string

The customer’s billing country. 2-letter ISO country code.

postal_code
string or null

The customer’s billing ZIP or postal code.

region
string or null

The customer’s billing state/province/region.

street_line_1
string or null

The customer’s billing address line 1 (Street address/PO Box).

street_line_2
string or null

The customer’s billing address line 2 (Apartment/Suite/Unit/Building).

subject
string or null

An optional summary description of the document.

required
Array of objects (document_item)

The individual line items that make up the expense. No more than 200 items are allowed in a request. To add more use subsequent update requests. Maximum items per document are limited up to 1000 items.

payment_method
string
Enum: "credit_card" "cash" "wire_transfer" "direct_debit" "check" "iou" "paypal" "other"

Payment method used.

payment_processor
string or null

The payment processor used to pay the expense.

payment_processor_id
string or null

The ID the payment_processor assigned to the payment.

custom_metadata
object or null

Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.

Responses

Request samples

Content type
application/json
{
  • "issue_date": "2023-09-01",
  • "po_number": "999",
  • "currency": "USD",
  • "tag_list": "consulting, office",
  • "payment_details": "string",
  • "notes": "string",
  • "contact": {
    },
  • "attachment": {
    },
  • "country": "US",
  • "postal_code": "91104",
  • "region": "CA",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "subject": "string",
  • "items": [
    ],
  • "payment_method": "credit_card",
  • "payment_processor": "stripe",
  • "payment_processor_id": "ch_999999999999",
  • "custom_metadata": { }
}

Response samples

Content type
application/json
{
  • "id": 927324,
  • "created_at": 1593260908,
  • "issue_date": "2023-09-01",
  • "po_number": "999",
  • "currency": "USD",
  • "tag_list": "consulting, office",
  • "payment_details": "string",
  • "notes": "string",
  • "contact": {
    },
  • "country": "US",
  • "postal_code": "91104",
  • "region": "CA",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "subject": "string",
  • "items": [
    ],
  • "taxes": [
    ],
  • "payments": [
    ],
  • "custom_metadata": { },
  • "subtotal_cents": 9375,
  • "discount_cents": 0,
  • "total_cents": 9375,
  • "state": "outstanding",
}

Retrieve an expense

Retrieves the details of an existing expense.

Authorizations:
API keyBearer token
path Parameters
id
required
string

The ID of the desired expense.

Responses

Response samples

Content type
application/json
{
  • "id": 927324,
  • "created_at": 1593260908,
  • "issue_date": "2023-09-01",
  • "po_number": "999",
  • "currency": "USD",
  • "tag_list": "consulting, office",
  • "payment_details": "string",
  • "notes": "string",
  • "contact": {
    },
  • "country": "US",
  • "postal_code": "91104",
  • "region": "CA",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "subject": "string",
  • "items": [
    ],
  • "taxes": [
    ],
  • "payments": [
    ],
  • "custom_metadata": { },
  • "subtotal_cents": 9375,
  • "discount_cents": 0,
  • "total_cents": 9375,
  • "state": "outstanding",
}

Update an expense

Updates an expense.

Authorizations:
API keyBearer token
path Parameters
id
required
integer

The ID of the expense to be updated.

Request Body schema: application/json
issue_date
string <date>

Date when the expense was issued.

po_number
string or null

Purchase order number.

currency
string

Three-letter ISO currency code, in uppercase.

tag_list
Array of strings or null

Multiple tags should be separated by commas.

payment_details
string or null

Detailed information about the payment.

notes
string or null

Extra notes about the expense.

required
contact (object) or object

Provider of your expense.

object (attachment)

Invoices and expenses can have attached files.

country
string

The customer’s billing country. 2-letter ISO country code.

postal_code
string or null

The customer’s billing ZIP or postal code.

region
string or null

The customer’s billing state/province/region.

street_line_1
string or null

The customer’s billing address line 1 (Street address/PO Box).

street_line_2
string or null

The customer’s billing address line 2 (Apartment/Suite/Unit/Building).

subject
string or null

An optional summary description of the document.

required
Array of objects (document_item)

The individual line items that make up the expense. No more than 200 items are allowed in a request. To add more use subsequent update requests. Maximum items per document are limited up to 1000 items.

payment_method
string
Enum: "credit_card" "cash" "wire_transfer" "direct_debit" "check" "iou" "paypal" "other"

Payment method used.

payment_processor
string or null

The payment processor used to pay the expense.

payment_processor_id
string or null

The ID the payment_processor assigned to the payment.

custom_metadata
object or null

Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.

Responses

Request samples

Content type
application/json
{
  • "issue_date": "2023-09-01",
  • "po_number": "999",
  • "currency": "USD",
  • "tag_list": "consulting, office",
  • "payment_details": "string",
  • "notes": "string",
  • "contact": {
    },
  • "attachment": {
    },
  • "country": "US",
  • "postal_code": "91104",
  • "region": "CA",
  • "street_line_1": "2311 North Los Robles Av.",
  • "street_line_2": "Apartment C",
  • "subject": "string",
  • "items": [
    ],
  • "payment_method": "credit_card",
  • "payment_processor": "stripe",
  • "payment_processor_id": "ch_999999999999",
  • "custom_metadata": { }
}

Response samples

Content type
application/json
{
  • "id": 927324,
  • "created_at": 1593260908,
  • "issue_date": "2023-09-01",
  • "po_number": "999",
  • "currency": "USD",
  • "tag_list": "consulting, office",
  • "payment_details": "string",
  • "notes": "string",
  • "contact": {