openapi: 3.0.3
info:
title: Anrok Customer certificates Transactions API
version: '1.1'
termsOfService: https://www.anrok.com/privacy-terms
contact:
email: support@anrok.com
license:
name: All rights reserved
url: https://www.anrok.com
x-logo:
url: https://global-uploads.webflow.com/632add85afcd1ac30aa74675/6357842d130e1f3e0e23d1fe_anrok_logo.svg
description: '# API reference
The Anrok API server is accessible at `https://api.anrok.com`.
All requests are HTTP POSTs with JSON in the body.
Authentication is via an HTTP header `Authorization: Bearer {apiKey}`.
The default rate limit for a seller account is 10 API requests per second.
'
servers:
- url: https://api.anrok.com
security:
- http: []
tags:
- name: Transactions
description: 'This documentation describes how to use Anrok''s Transactions API to synchronize transactions between Anrok and your billing system, as well as calculate sales tax for new invoices. Use of this API is generally recommended for sellers with custom billing systems or workflows that prevent you from using one of our pre-built platform integrations. Sellers utilizing Stripe Subscriptions or Checkout may also use this API to calculate and add tax on initial invoices, while continuing to use Anrok''s Stripe integration to manage tax for subsequent billing cycles.
# Invoice lifecycle
1. When an invoice is created: the billing system should call the `createEphemeral` endpoint to calculate the sales tax amount.
1. When an invoice is updated: same as above.
1. When an invoice is finalized and ready to send to the customer: the billing system should call the `createOrUpdate` endpoint so that the transaction is recorded in Anrok.
1. When an invoice is paid: Anrok does not need to be notified. Sellers are required to remit sales tax to a state upon invoice, not receipt of payment.
While the above covers a standard invoice lifecycle, the Transactions API also includes endpoints for exceptional states like voiding and negating invoices, which are described below.
'
paths:
/v1/seller/transactions/createOrUpdate:
post:
tags:
- Transactions
summary: Create or update transaction
description: Given the details of an invoice, calculate sales tax and save it as a transaction in Anrok. Saved transactions are used by Anrok to file sales tax returns and monitor sales thresholds.
operationId: transactionsCreateOrUpdate
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CreateOrUpdateTransaction'
example:
id: stripe:in_1JSW342eZvKYlo2C
currencyCode: usd
accountingTime: '2022-01-02T03:30:00Z'
accountingTimeZone: UTC
lineItems:
- id: item-1
productExternalId: saas-product-1
amount: 15000
isTaxIncludedInAmount: false
quantity: '1'
- id: item-2
productExternalId: saas-product-2
amount: 31000
isTaxIncludedInAmount: true
quantity: '12.3'
- id: item-3
productExternalId: not-taxable-3
amount: 24000
customerAddress:
country: us
line1: 1450 Cherokee St
city: Denver
region: CO
postalCode: '80204'
shipFromAddress:
country: us
line1: 230 S LaSalle St
city: Chicago
region: IL
postalCode: '60604'
required: true
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/CreateOrUpdateTransactionSuccess'
example:
version: 1
taxAmountToCollect: 722
lineItems:
- id: item-1
taxAmountToCollect: 722
preTaxAmount: '15000'
jurises:
- name: Colorado
taxes: null
notTaxedReason:
type: productNotTaxed
- name: Denver (local)
taxes:
- taxName: Tax
taxableAmount: '15000'
taxAmount: '721.5'
taxRate: '0.0481'
notTaxedReason: null
- id: item-2
taxAmountToCollect: 0
preTaxAmount: '29577.3304'
jurises:
- name: Colorado
taxes: null
notTaxedReason:
type: productNotTaxed
- name: Denver (local)
taxes:
- taxName: Tax
taxableAmount: '29577.3304'
taxAmount: '1422.6696'
taxRate: '0.0481'
notTaxedReason: null
- id: item-3
taxAmountToCollect: 0
preTaxAmount: '24000'
jurises:
- name: Colorado
taxes: null
notTaxedReason:
type: productNotTaxed
preTaxAmount: '68577.3304'
jurisSummaries:
- name: Colorado
notTaxedReasons:
- type: productNotTaxed
- name: Denver (local)
notTaxedReasons: null
'400':
$ref: '#/components/responses/CreateTransactionBadRequest'
'409':
description: Conflict
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/CreateTransactionCannotComputeTaxAmount'
- $ref: '#/components/schemas/CreateTransactionCannotUpdate'
examples:
taxDateTooFarInFuture:
$ref: '#/components/examples/ConflictTaxDateTooFarInFuture'
taxDateTooFarInPast:
$ref: '#/components/examples/ConflictTaxDateTooFarInPast'
accoutingTimeZoneNotSetForSeller:
$ref: '#/components/examples/ConflictAccountingTimeZoneNotSetForSeller'
productExternalIdUnknown:
$ref: '#/components/examples/ConflictProductExternalIdUnknown'
'429':
$ref: '#/components/responses/RateLimit'
x-codeSamples:
- lang: cURL
source: "apiToken='sxxx/saxxx/secret.xxx'\n\ncurl -X POST https://api.anrok.com/v1/seller/transactions/createOrUpdate \\\n -H 'Content-Type: application/json' \\\n -H \"Authorization: Bearer $apiToken\" \\\n -d '{\n \"id\": \"stripe:in_1JSW342eZvKYlo2C\",\n \"currencyCode\": \"usd\",\n \"accountingTime\": \"2022-01-02T03:30:00Z\",\n \"accountingTimeZone\": \"UTC\",\n \"lineItems\": [{\n \"id\": \"item-1\",\n \"productExternalId\": \"saas-product-1\",\n \"amount\": 15000,\n \"isTaxIncludedInAmount\": false,\n \"quantity\": \"1\"\n },\n {\n \"id\": \"item-2\",\n \"productExternalId\": \"saas-product-2\",\n \"amount\": 31000,\n \"isTaxIncludedInAmount\": true,\n \"quantity\": \"12.3\"\n },\n {\n \"id\": \"item-3\",\n \"productExternalId\": \"not-taxable-3\",\n \"amount\": 24000\n }],\n \"customerAddress\": {\n \"country\": \"us\",\n \"line1\": \"1450 Cherokee St\",\n \"city\": \"Denver\",\n \"region\": \"CO\",\n \"postalCode\": \"80204\"\n },\n \"shipFromAddress\": {\n \"country\": \"us\",\n \"line1\": \"230 S LaSalle St\",\n \"city\": \"Chicago\",\n \"region\": \"IL\",\n \"postalCode\": \"60604\"\n }\n }'\n"
/v1/seller/transactions/createEphemeral:
post:
tags:
- Transactions
summary: Create ephemeral transaction
description: Given the details of an invoice, calculate sales tax without saving the transaction in Anrok. Ephemeral transactions are not used by Anrok to file sales tax returns or monitor sales thresholds.
operationId: transactionsCreateEphemeral
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CreateEphemeralTransaction'
example:
currencyCode: usd
accountingTime: '2022-01-02T03:30:00Z'
accountingTimeZone: UTC
lineItems:
- id: item-1
productExternalId: saas-product-1
amount: 15000
isTaxIncludedInAmount: false
quantity: '1'
- id: item-2
productExternalId: saas-product-2
amount: 31000
isTaxIncludedInAmount: true
quantity: '12.3'
- id: item-3
productExternalId: not-taxable-3
amount: 24000
customerAddress:
country: us
line1: 1450 Cherokee St
city: Denver
region: CO
postalCode: '80204'
shipFromAddress:
country: us
line1: 230 S LaSalle St
city: Chicago
region: IL
postalCode: '60604'
required: true
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/CreateEphemeralTransactionSuccess'
example:
taxAmountToCollect: 722
lineItems:
- id: item-1
taxAmountToCollect: 722
preTaxAmount: '15000'
jurises:
- name: Colorado
taxes: null
notTaxedReason:
type: productNotTaxed
- name: Denver (local)
taxes:
- taxName: Tax
taxableAmount: '15000'
taxAmount: '721.5'
taxRate: '0.0481'
notTaxedReason: null
- id: item-2
taxAmountToCollect: 0
preTaxAmount: '29577.3304'
jurises:
- name: Colorado
taxes: null
notTaxedReason:
type: productNotTaxed
- name: Denver (local)
taxes:
- taxName: Tax
taxableAmount: '29577.3304'
taxAmount: '1422.6696'
taxRate: '0.0481'
notTaxedReason: null
- id: item-3
taxAmountToCollect: 0
preTaxAmount: '24000'
jurises:
- name: Colorado
taxes: null
notTaxedReason:
type: productNotTaxed
preTaxAmount: '68577.3304'
jurisSummaries:
- name: Colorado
notTaxedReasons:
- type: productNotTaxed
- name: Denver (local)
notTaxedReasons: null
'400':
$ref: '#/components/responses/CreateTransactionBadRequest'
'409':
description: Conflict
content:
application/json:
schema:
$ref: '#/components/schemas/CreateTransactionCannotComputeTaxAmount'
examples:
taxDateTooFarInFuture:
$ref: '#/components/examples/ConflictTaxDateTooFarInFuture'
taxDateTooFarInPast:
$ref: '#/components/examples/ConflictTaxDateTooFarInPast'
accoutingTimeZoneNotSetForSeller:
$ref: '#/components/examples/ConflictAccountingTimeZoneNotSetForSeller'
productExternalIdUnknown:
$ref: '#/components/examples/ConflictProductExternalIdUnknown'
'429':
$ref: '#/components/responses/RateLimit'
x-codeSamples:
- lang: cURL
source: "apiToken='sxxx/saxxx/secret.xxx'\n\ncurl -X POST https://api.anrok.com/v1/seller/transactions/createEphemeral \\\n -H 'Content-Type: application/json' \\\n -H \"Authorization: Bearer $apiToken\" \\\n -d '{\n \"currencyCode\": \"usd\",\n \"accountingTime\": \"2022-01-02T03:30:00Z\",\n \"accountingTimeZone\": \"UTC\",\n \"lineItems\": [{\n \"id\": \"item-1\",\n \"productExternalId\": \"saas-product-1\",\n \"amount\": 15000,\n \"isTaxIncludedInAmount\": false,\n \"quantity\": \"1\"\n },\n {\n \"id\": \"item-2\",\n \"productExternalId\": \"saas-product-2\",\n \"amount\": 31000,\n \"isTaxIncludedInAmount\": true,\n \"quantity\": \"12.3\"\n },\n {\n \"id\": \"item-3\",\n \"productExternalId\": \"not-taxable-3\",\n \"amount\": 24000\n }],\n \"customerAddress\": {\n \"country\": \"us\",\n \"line1\": \"1450 Cherokee St\",\n \"city\": \"Denver\",\n \"region\": \"CO\",\n \"postalCode\": \"80204\"\n },\n \"shipFromAddress\": {\n \"country\": \"us\",\n \"line1\": \"230 S LaSalle St\",\n \"city\": \"Chicago\",\n \"region\": \"IL\",\n \"postalCode\": \"60604\"\n }\n }'\n"
/v1/seller/transactions/createNegation:
post:
tags:
- Transactions
summary: Create negation
description: Creates a new transaction that is the exact inverse of the given transaction. The sale prices and tax amounts will add up to zero.
operationId: transactionsCreateNegation
requestBody:
$ref: '#/components/requestBodies/CreateNegation'
responses:
'200':
$ref: '#/components/responses/EmptyResponse'
'400':
$ref: '#/components/responses/CreateNegationBadRequest'
'409':
$ref: '#/components/responses/CreateNegationConflict'
'429':
$ref: '#/components/responses/RateLimit'
x-codeSamples:
- lang: cURL
source: "apiToken='sxxx/saxxx/secret.xxx'\n\ncurl -X POST https://api.anrok.com/v1/seller/transactions/createRefund \\\n -H 'Content-Type: application/json' \\\n -H \"Authorization: Bearer $apiToken\" \\\n -d '{\n \"originalTransactionId\": \"stripe:in_1JSW342eZvKYlo2C\",\n \"newTransactionId\": \"stripe:in_1JSW342eZvKYlo2C_refund\"\n }'"
/v1/seller/transactions/id:{transactionId}/void:
parameters:
- $ref: '#/components/parameters/TransactionId'
post:
tags:
- Transactions
summary: Void transaction
description: Mark a previously-created transaction as void. It will no longer be included in returns or sales totals.
operationId: transactionsVoid
requestBody:
content:
application/json:
schema:
type: object
properties:
transactionExpectedVersion:
description: The expected transaction version. The void will fail if this is not the latest version of the transaction.
type: integer
format: int32
examples:
emptyExample:
value: {}
summary: Empty request body
expectVersion:
value:
transactionExpectedVersion: 1
summary: Expected transaction version
required: true
responses:
'200':
$ref: '#/components/responses/EmptyResponse'
'409':
description: Conflict
content:
application/json:
schema:
type: object
properties:
type:
type: string
enum:
- transactionIdNotFound
- transactionExpectedVersionMismatch
- transactionFrozenForFiling
example:
type: transactionIdNotFound
'429':
$ref: '#/components/responses/RateLimit'
x-codeSamples:
- lang: cURL
source: "apiToken='sxxx/saxxx/secret.xxx'\n\ncurl -X POST https://api.anrok.com/v1/seller/transactions/id:stripe:in_1JSW342eZvKYlo2C/void \\\n -H 'Content-Type: application/json' \\\n -H \"Authorization: Bearer $apiToken\" \\\n -d '{}'"
/v1/seller/transactions/list:
post:
tags:
- Transactions
summary: List transactions
description: 'Lists transactions in Anrok. These can be filtered by the time they were last modified or by the filing they are associated with.
This endpoint is a premium feature. Please contact hello@anrok.com for more information to enable this on your seller account.
'
operationId: transactionsList
requestBody:
$ref: '#/components/requestBodies/ListTransactions'
responses:
'200':
$ref: '#/components/responses/ListTransactionsSuccess'
'400':
$ref: '#/components/responses/ListTransactionsBadRequest'
'409':
$ref: '#/components/responses/ListTransactionsConflict'
'429':
$ref: '#/components/responses/RateLimit'
x-codeSamples:
- lang: cURL
source: "apiToken='sxxx/saxxx/secret.xxx'\n\ncurl -X POST https://api.anrok.com/v1/seller/transactions/list \\\n -H 'Content-Type: application/json' \\\n -H \"Authorization: Bearer $apiToken\" \\\n -d '{\n \"filter\": {\n \"type\": \"lastModifiedAfter\",\n \"value\": \"2025-08-08T16:00:00.000Z\"\n }\n }'\n"
components:
responses:
ListTransactionsConflict:
description: Conflict
content:
application/json:
schema:
type: object
properties:
type:
type: string
enum:
- invalidCursor
- listTransactionsApiNotEnabled
examples:
invalidCursor:
value:
type: invalidCursor
summary: Invalid cursor
listTransactionsApiNotEnabled:
value:
type: listTransactionsApiNotEnabled
summary: List transactions API not enabled
CreateNegationConflict:
description: Conflict
content:
application/json:
schema:
type: object
properties:
type:
type: string
enum:
- transactionIdNotFound
- transactionExpectedVersionMismatch
- transactionIsAlreadyANegation
- duplicateTransactionId
example:
type: transactionExpectedVersionMismatch
ListTransactionsSuccess:
description: OK
content:
application/json:
schema:
type: object
properties:
transactions:
description: The list of transactions.
type: array
items:
oneOf:
- $ref: '#/components/schemas/NormalTransactionResponse'
- $ref: '#/components/schemas/VoidedTransactionResponse'
nextCursor:
description: The cursor to use for pagination.
type: string
examples:
- eyJleGFtcGxlIjoidGhpcyBpcyBhbiBleGFtcGxlIGN1cnNvciJ9
hasMore:
description: Whether there are more transactions to fetch.
type: boolean
RateLimit:
description: Too Many Requests
headers:
Retry-After:
description: Number of seconds to wait for rate limit to reset.
schema:
type: integer
content:
text/plain:
schema:
type: string
example: You've exceeded your API limit of 10 per second
CreateNegationBadRequest:
description: Bad Request
content:
application/json:
schema:
type: string
examples:
missingRequestProperty:
summary: Required property missing
value: 'Request body: "newTransactionId": Required.'
EmptyResponse:
description: OK
content:
application/json:
schema:
type: object
example: {}
CreateTransactionBadRequest:
description: Bad Request
content:
application/json:
schema:
type: string
examples:
missingRequiredProperty:
value: 'Request body: "lineItems": Required.'
summary: Missing required property
missingCustomerAddress:
value: 'Request body: "customerAddress": Invalid input.'
summary: Missing "customerAddress"
usAddressMissingCountry:
value: 'Request body: "customerAddress": Unrecognized key(s) in object: ''state'', ''zipCode''.'
summary: A US customer address must include the "country" property.
redundantTimeZoneProvided:
value: 'Request body: Cannot specify both accountingDate and accountingTimeZone.'
summary: If accountingDate is provided then accountingTimeZone must be omitted.
missingAccountingDate:
value: 'Request body: Must specify either accountingDate or accountingTimeZone.'
summary: Not enough info to determine accounting date
ListTransactionsBadRequest:
description: Bad Request
content:
text/plain:
schema:
type: string
examples:
invalidFilterProvided:
value: 'Request body: "filter": Invalid input.'
summary: Invalid filter
invalidLastModifiedAfterFilterValueProvided:
value: 'Request body: "filter": "value": Invalid format; expecting "YYYY-MM-DDTHH:mm:ss.dddZ".'
summary: Invalid lastModifiedAfter filter value
invalidFilingInfoFilterValueProvided:
value: 'Request body: "filter": "value": "jurisId": Invalid juris ID: "invalid-juris-id".'
summary: Invalid filingInfo filter value
invalidLimitProvided:
value: 'Request body: "limit": Number must be less than or equal to 20.'
summary: Invalid limit
cursorAndFilterBothProvided:
value: 'Request body: cursor and filter cannot both be provided.'
summary: Cursor and filter cannot both be provided
schemas:
FilingInfoFilter:
type: object
properties:
type:
type: string
enum:
- filingInfo
value:
type: object
description: Only return transactions that are associated with the specified filing.
properties:
filingAssociationStatus:
type: string
enum:
- associated
jurisId:
type: string
examples:
- us-MA
jurisFilingId:
type: string
examples:
- 2025-01
NormalTransactionBody:
type: object
properties:
accountingDate:
description: The date that this transaction occurred, for accounting purposes.
type: string
format: date
example: '2025-01-01'
taxDate:
description: The date to use for tax calculations.
type: string
format: date
example: '2025-01-01'
currencyCode:
description: Three letter ISO currency code (case insensitive).
type: string
minLength: 3
maxLength: 3
examples:
- USD
- GBP
- EUR
customer:
type: object
nullable: true
properties:
id:
description: The Anrok customer ID.
type: string
example: cus_1234567890
name:
description: The name of the customer.
type: string
nullable: true
example: John Doe
addresses:
type: array
items:
type: object
properties:
address:
$ref: '#/components/schemas/CustomerAddress'
example:
address:
city: null
line1: null
region: TX
country: US
postalCode: '10101'
inputAmount:
type: integer
format: int64
description: The input amount in the smallest denomination of the currency (e.g. cents or pennies).
example: 39800
preTaxAmount:
type: string
format: Decimal
description: The pre-tax amount in the smallest denomination of the currency (e.g. cents or pennies).
example: '39800'
taxAmountDue:
allOf:
- $ref: '#/components/schemas/TaxAmountDue'
- example:
inclusive: '0'
exclusive: '2467.6'
total: '2467.6'
taxAmountAdded:
type: object
properties:
expected:
type: integer
format: int64
description: The expected tax amount to add in the smallest denomination of the currency (e.g. cents or pennies).
example: 2468
seen:
type: integer
format: int64
description: The tax amount that Anrok saw was added in the smallest denomination of the currency (e.g. cents or pennies).
example: 2468
invoiceTotalAmountExpected:
type: integer
format: int64
description: The expected total amount of the invoice in the smallest denomination of the currency (e.g. cents or pennies).
example: 42268
jurisSummaries:
type: array
items:
allOf:
- $ref: '#/components/schemas/JurisSummary'
- example:
id: us-TX
name: Texas
preTaxAmount: '39800'
taxAmountDue:
inclusive: '0'
exclusive: '2467.6'
total: '2467.6'
taxIdValidation:
processedTaxIds:
- taxId: '1234567890'
isValid: true
lineItems:
type: array
items:
allOf:
- $ref: '#/components/schemas/LineItem'
- example:
id: li_1234567890
product:
internalId: sp3hgz76gve3
externalId: PLU1
name: Product 1
productTaxCategory:
type: standard
id: saasBusiness
name: SaaS - General, B2B
quantity: null
unitPrice: null
inputAmount: 39800
preTaxAmount: '39800'
taxAmountDue:
inclusive: '0'
exclusive: '2467.6'
total: '2467.6'
jurises:
- id: us-TX
name: Texas
calc:
isRemitting: true
taxes:
- id: ''
name: Texas
nonTaxableAmount: '7960'
exemptions: []
taxableAmount: '31840'
rate: '0.0625'
taxAmount:
inclusive: '0'
exclusive: '1990'
- id: '4109000'
name: Hill County
nonTaxableAmount: '7960'
exemptions: []
taxableAmount: '31840'
rate: '0.005'
taxAmount:
inclusive: '0'
exclusive: '159.2'
- id: '2109108'
name: Aquilla
nonTaxableAmount: '7960'
exemptions: []
taxableAmount: '31840'
rate: '0.01'
taxAmount:
inclusive: '0'
exclusive: '318.4'
CreateTransactionCannotUpdate:
type: object
description: Error updating transaction
properties:
type:
type: string
enum:
- transactionFrozenForFiling
LastModifiedAfterFilter:
type: object
properties:
type:
type: string
enum:
- lastModifiedAfter
value:
type: string
format: date-time
description: Only return transactions that were last modified after this time in Anrok. Must be an ISO 8601 date-time in UTC.
example: '2025-01-01T00:00:00Z'
TaxAmountDue:
description: The tax amount due in the smallest denomination of the currency (e.g. cents or pennies).
type: object
properties:
inclusive:
description: The inclusive tax amount in the smallest denomination of the currency (e.g. cents or pennies).
type: string
format: Decimal
example: '100.00'
exclusive:
description: The exclusive tax amount in the smallest denomination of the currency (e.g. cents or pennies).
type: string
format: Decimal
example: '10.00'
total:
description: The total tax amount in the smallest denomination of the currency (e.g. cents or pennies).
type: string
format: Decimal
example: '110.00'
NormalTransactionResponse:
description: Normal transaction
type: object
allOf:
- type: object
properties:
type:
type: string
enum:
- normal
- $ref: '#/components/schemas/CommonTransactionProperties'
- type: object
properties:
body:
$ref: '#/components/schemas/NormalTransactionBody'
NotTaxedReason:
type: object
properties:
type:
description: The reason a line item is not taxed.
type: string
enum:
- exempt
- jurisHasNoTax
- notCollecting
- productNotTaxed
reason:
description: The detailed reason for an exemption. Only set when the type is 'exempt'.
type: object
properties:
type:
enum:
- reverseCharge
- customerExempt
- transactionExempt
JurisSummary:
description: Summary of the tax amount due and tax ID validation for a jurisdiction.
type: object
properties:
id:
description: The ID of the jurisdiction.
type: string
example: us-TX
name:
description: The name of the jurisdiction.
type: string
example: Texas
preTaxAmount:
description: The pre-tax amount in the smallest denomination of the currency (e.g. cents or pennies).
type: string
format: Decimal
example: '100.00'
taxAmountDue:
$ref: '#/components/schemas/TaxAmountDue'
taxIdValidation:
type: object
properties:
processedTaxIds:
description: The tax IDs that were processed.
type: array
items:
type: object
properties:
taxId:
description: The tax ID.
type: string
example: '1234567890'
isValid:
description: Whether the tax ID is valid.
type: boolean
CustomerTaxId:
type: object
description: The customer VAT registration number for a non-US country
properties:
type:
type: string
enum:
- genericVatNumber
- euVrn
description: This setting is purely met
# --- truncated at 32 KB (56 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/anrok/refs/heads/main/openapi/anrok-transactions-api-openapi.yml