openapi: 3.0.0
info:
version: 2.0.0
title: Anchorage Digital API Reference Addresses Tax API
contact:
email: api@anchorage.com
description: "# Introduction\n*CONFIDENTIAL: Please do not distribute this documentation externally without prior Anchorage Digital approval.*\n\n\nThe Anchorage Digital REST API v2.0 provides a set of operations and resources that allow Anchorage Digital clients and partners to:\n - Programmatically transfer funds from an Anchorage Digital vault or wallet without human intervention\n - Create and list deposit addresses in a vault\n - Read and monitor vault balances\n - Query transaction history including deposits\n - Request quotes from and execute trades with the Anchorage Digital trading desk\n\n\nWant help or to share your opinion on how this API works for you? Please contact api@anchorage.com.\n\n\n# Authentication and Security\n\nThe Anchorage Digital API performs authentication and authorization via a combination of:\n\n\n* An API key, which is a bearer token\n\n* A permission group signed by the user's organization, which is linked to the API key\n\n* An Ed25519 Signature, which comes from a user-generated key and is required for certain requests\n\n\n## Permission Groups\n\n\nA permission group acts as a set of rules for how an organization and its resources can be accessed. Permission groups are created independently of API keys, and new permission groups must be created prior to making an API key.\n\n\nEach permission group has a name, a description and a set of permissions which can be applied to your organization's vaults. Updating, creating and deleting permissions groups require a quorum of approvals. After creation, a permission group can be freely assigned to an unlimited number of API keys.\n\n\nEach API key inherits its permissions from the associated permission group. When the permission group is updated, all API keys associated with it will inherit the updated permission set. If a permission group is deleted, all associated API keys will no longer work.\n\n\nEach organization is created with a default permission group that allows read-only access. This permission group may be modified or deleted at any time, and no API keys are created by default with this permission group.\n\n\n### Permissions\n\n\nPossible vault permissions include the following:\n\n\n
\n \n | Read vault activity (READ) | \n See an overview of your vault(s) and wallets. Read vault details, balances, asset types, transaction history and deposit addresses. | \n
\n \n | Create address (CREATE_DEPOSIT_ADDRESS) | \n Receive deposits in the vault from external sources. Create and read deposit addresses. | \n
\n \n | Transfer funds (TRANSFER) | \n This permission is configurable to enable an API key endowed with this permission to either 1) Transfer funds to any Anchorage Digital institutional account, including those outside of your organization or 2) Transfer funds to any blockchain address not custodied by Anchorage Digital that has gone through quorum approval. | \n
\n \n | Propose and accept settlements (PROPOSE_ACCEPT_SETTLEMENTS) | \n This is an Atlas specific permission for initiating settlements. | \n
\n \n | Authorize settlements (AUTHORIZE_SETTLEMENTS) | \n This is an Atlas specific permission for authorizing settlements after they've been proposed or accepted. | \n
\n
\n\n\nThere are also special vault permissions for enabled by Anchorage Digital on a per-organization basis:\n\nAdditionally, there are global permissions which apply to the entire organization:\n\n\n\n \n | Initiate withdrawals (INITIATE_WITHDRAWAL) | \n Initiate withdrawals to external destinations. All withdrawals require quorum approval through the Anchorage Digital mobile app. | \n
\n \n | Execute trades (TRADE) | \n Request for quotes (RFQ) from the Anchorage Digital trading desk. Create and accept quotes. Read data of trades and settlements created by this key. | \n
\n \n | Read trade activity (READ_TRADE) | \n Read trade activity and trade settlements data of your organization. | \n
\n \n | Read lending activity (LENDER_READ) | \n Read lending activity of your organization. | \n
\n \n | Read facility data (FACILITY_ONLY) | \n Read lending facility data. | \n
\n \n | Read deposit attribution activity (READ_DEPOSIT_ATTRIBUTION) | \n Read deposit attribution activity of your organization. | \n
\n \n | Manage deposit attributions (DEPOSIT_ATTRIBUTION) | \n Read deposit attribution activity of your organization. Perform deposit attributions. | \n
\n \n | Initiate Staking and Unstaking (STAKE) | \n Initiate staking or unstaking operation. All operations require quorum approval through the Anchorage Digital mobile app. | \n
\n
\n\n\n### Example Workflow - Allow transfers from specific vaults\n\nTo create an API key with the ability to transfer funds from an Anchorage Digital vaults or wallet, a permission group must first be created with the **Transfer funds** permission for the desired source vaults. Creating this permission group requires a quorum of approvals on the Anchorage Digital iOS app. Once the creation is confirmed, any number of API keys may be created with this permission group in the Anchorage Digital Web Dashboard under the API 2.0 section.\n\nTo add additional permissions to the API key, update the associated permission group through the Anchorage Digital Web Dashboard. To revoke any permissions, the individual API key may be revoked, or the permission group may be updated or deleted to remove Transfer access.\n\n## API Keys\n\nAll API requests must be made over HTTPS and must include authentication using the following scheme.\n\n\n\n### Generating an API Key\n\nIn order to make a valid API request, you must first create an API key. API keys can be created and managed in the Anchorage Digital Web Dashboard under the [API 2.0 tab](https://anchoragelogin.com/api). When you create an API key, there are 3 pieces of information you will need to remember:\n - API access key\n - Ed25519 public key (optional for read-only requests)\n - Ed25519 private/signing key (optional for read-only requests)\n\nYou must generate an Ed25519 signing key pair and save the public portion in the Anchorage Digital Web Dashboard when creating the API access key. The signing key pair is used for added security with sensitive requests.\n\nPlease note, Anchorage Digital cannot recover your API access key or private signing key if you forget them. You may generate a new access key and signing key at any time if you lose access.\n\n### API Key Permissions\n\nEach API key is associated with a permission group. This permission group specifies the permitted actions for all associated API keys. Read more about permission groups [here](#section/Authentication-and-Security/Permission-Groups).\n\n### Creating a request\n\nAll requests must include the `Api-Access-Key` header, which contains your API access key as a string.\n\nEndpoints that require a signature must include the `Api-Signature` and `Api-Timestamp` headers. Read more about signatures [here](#section/Authentication-and-Security/Signatures).\n\nAll request bodies must be valid JSON and have the content type `application/json`.\n\n## Request Signatures\n\nCertain endpoints require an Ed25519 signature to be provided alongside the API key. These endpoints will specify the `Api-Signature` and `Api-Timestamp` headers as additional parameters.\n\nSignatures are optional unless explicitly required, but are encouraged for all requests. If a signature is provided, it will be verified.\n\n### Signing Keys\n\nA signing key pair is generated by the user and the corresponding public key must be provided when creating an API key.\n\nWhen creating an API key, you will be prompted to provide an Ed25519 public key. You must use the associated Ed25519 signing key (private key) when creating signatures for requests from this API key.\n\nPlease note that signing keys (Ed25519 private keys) should be stored securely by the user. The signing key should only be used to derive request signatures and should never be sent in a request. Anchorage Digital will never request you share your private key.\n\n### Generating a Signing Key\n\nThe user must securely generate an Ed25519 key pair on their own hardware and retain both the public and private portions. The Anchorage Digital API accepts a 64-character (32 bytes) hex-encoded Ed25519 public key when creating an API access key.\n\n\n#### Code sample (Python)\n\n*Generate a new signing key pair*\n\n```python\n# https://pypi.org/project/PyNaCl/\n\nimport nacl\nimport nacl.signing\nimport secrets\n\nseed = secrets.token_bytes(32)\n\n# Generate a new random signing key\nsigning_key = nacl.signing.SigningKey(seed)\n\n# Obtain the hex-encoded signing key\nprint('Signing key:')\nprint(signing_key.encode().hex())\n\n# Obtain the hex-encoded verify key for the given signing key\n# Use this in the Anchorage Digital Web Dashboard when creating an API key\nprint('Public key:')\nprint(signing_key.verify_key.encode().hex())\n```\n\n\n### Signing a Request\n\nTo sign a request, generate a request signature using the Ed25519 private (signing) key and provide it alongside the request in the `Api-Signature` header.\n\nTo create a request signature, first concatenate the `timestamp`, `method`, `request path`, and `body` into a string. Then, create a signature of this message using the Ed25519 private key and hex-encode the output. Use this value as the `Api-Signature` header and use the `timestamp` value as the `Api-Timestamp` header.\n\n- The `method` is an uppercase HTTP method (ex. `GET`, `POST`, `DELETE`)\n- The `request path` should contain all query parameters (ex. `/v2/transfers?foo=bar&baz=bang`)\n- The `body` is a stringified HTTP request body\n- The `body` should be omitted if the request does not contain a body (ex. a `GET` or `DELETE` request)\n- The `timestamp` is the same as the `Api-Timestamp` header\n- The `timestamp` is a number of seconds since the Unix Epoch in UTC, and must be within one minute of the API service's time when the request is received\n\n### Reference signature\n\nTo verify your signature generation code is correct, generate a signature for the following request and timestamp using the provided signing key. If the generated signature matches the signature below, your signature generation code is correct.\n\n\n\n \n | Timestamp | \n 1577880000 | \n
\n \n | HTTP Method (Uppercase) | \n POST | \n
\n \n | HTTP Path + query | \n /v2/transfers?foo=bar&baz=bang | \n
\n \n | HTTP Body | \n {\"source\": {\"id\": \"1c920f4241b78a1d483a29f3c24b6c4c\", \"type\": \"VAULT\"}, \"assetType\": \"ETH\", \"destination\": {\"id\": \"55e89d4a644d736b01533a2ea9b32a20\", \"type\": \"VAULT\"}, \"amount\": \"1000.00000000\"} | \n
\n \n | Signing Key (Ed25519 Private Key Seed) | \n 0101010101010101010101010101010101010101010101010101010101010101 | \n
\n \n | Public Key | \n 8a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c | \n
\n \n | Signature | \n 4bf42054bf7db1f8a2a2bc83d2a108502ee7a9d2ac7a2738adc2f932922446786fb9be1bd1eb475023296c6cba4ddbe28b04baca4b7521b1f1840a4ffd2b4d0d | \n
\n
\n\n## Reference clients\n\n### Python (with `requests` library)\n\n*Authorize and sign requests*\n\n```python\n\n# https://pypi.org/project/PyNaCl/\n\nfrom nacl import signing\n\nimport time\n\nimport requests\n\n\nclass AnchorageAuth(requests.auth.AuthBase):\n ACCESS_KEY_HEADER = \"Api-Access-Key\"\n SIGNATURE_HEADER = \"Api-Signature\"\n TIMESTAMP_HEADER = \"Api-Timestamp\"\n\n access_key: str\n signing_key: signing.SigningKey\n\n def __init__(self, access_key: str, signing_key_seed: bytes):\n self.access_key = access_key\n self.signing_key = signing.SigningKey(signing_key_seed)\n\n def __call__(self, r: requests.PreparedRequest):\n r.headers[self.ACCESS_KEY_HEADER] = self.access_key\n\n timestamp = str(int(time.time()))\n method = r.method.upper() if r.method else \"GET\"\n body: bytes = bytes()\n if r.body and isinstance(r.body, bytes):\n body = r.body\n elif r.body and isinstance(r.body, str):\n body = bytearray(r.body, \"utf-8\")\n message = b\"\".join(\n [bytearray(timestamp, \"utf-8\"), bytearray(method, \"utf-8\"), bytearray(r.path_url, \"utf-8\"), body]\n )\n signature = self.signing_key.sign(message).signature.hex()\n r.headers[self.SIGNATURE_HEADER] = signature\n r.headers[self.TIMESTAMP_HEADER] = timestamp\n return r\n\n\n# load secrets\n\n# Use the API key generated in the Anchorage Digital Web Dashboard\n\naccess_key = ...\n\n# Use the Ed25519 signing private key\n\nsigning_key_str = ... # load the raw string\n\nsigning_key = bytes(bytearray.fromhex(signing_key_str))\n\ndata = {}\n\nanchorage_auth = AnchorageAuth(access_key, signing_key)\n\nr = requests.post(\"https://api.anchorage.com/v2/transfers\", data=data, auth=anchorage_auth)\n\n```\n\n### Ruby - Reproduce reference signature\n```ruby\n require \"ed25519\"\n require \"net/http\"\n require \"time\"\n\n def hex_to_bin(s)\n [s].pack('H*')\n end\n\n def bin_to_hex(s)\n s.unpack('H*').first\n end\n\n private_key_seed_hex = '0101010101010101010101010101010101010101010101010101010101010101'\n public_key_hex = '8a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c'\n key_pair_hex = private_key_seed_hex + public_key_hex\n\n key_pair = hex_to_bin(key_pair_hex)\n\n signing_key = Ed25519::SigningKey.from_keypair(key_pair)\n\n timestamp = '1577880000' # Time.now.to_i.to_s\n\n req = Net::HTTP::Post.new('/v2/transfers?foo=bar&baz=bang')\n req.body = '{\"source\": {\"id\": \"1c920f4241b78a1d483a29f3c24b6c4c\", \"type\": \"VAULT\"}, \"assetType\": \"ETH\", \"destination\": {\"id\": \"55e89d4a644d736b01533a2ea9b32a20\", \"type\": VAULT\"}, \"amount\": \"1000.00000000\"}'\n\n signature = signing_key.sign(timestamp + req.method + req.path + req.body)\n\n req['Api-Access-Key'] = 'YOUR_ACCESS_KEY'\n req['Api-Timestamp'] = timestamp\n req['Api-Signature'] = bin_to_hex(signature)\n\n puts bin_to_hex(signature)\n```\n\n# Errors\n\n\nThe Anchorage Digital API returns standard HTTP error codes for each API request.\n\n\n\n \n | Response Code | \n Description | \n
\n
\n | 200 OK | \n The request was successful. | \n
\n \n | 400 Bad Request | \n The request was improperly formed and could not be understood by the server, often due to invalid syntax, insufficient funds, or a missing required parameter. | \n
\n \n | 401 Unauthorized | \n The request was missing a valid API key. | \n
\n \n | 403 Forbidden | \n The provided API key does not have permission to perform the requested action. | \n
\n \n | 404 Not Found | \n The requested resource does not exist. | \n
\n \n | 409 Conflict | \n The requested resource cannot proceed with the requested action because it is not in the required state. | \n
\n \n | 429 Too Many Requests | \n Too many requests have been sent in a given amount of time. | \n
\n \n \n 500 Internal Server Error\n \n 502 Bad Gateway\n \n 503 Service Unavailable\n \n 504 Gateway Timeout\n | \n Something went wrong on Anchorage’s side. We have been alerted and are working on it. | \n
\n
\n\n\nIn addition to returning HTTP error codes for failed requests, the Anchorage Digital API includes a readable error message describing what went wrong in the response body.\n\n\n\n\n\n# Idempotency\n\n\nCertain endpoints support idempotent requests so that a given request can be safely retried without performing the same operation twice. For example, if a request to transfer funds does not respond due to network issues, you can retry the request using the same idempotent ID to ensure that only one transfer is created.\n\n\nEndpoints that support idempotent requests have an optional `idempotentId` field that can be included in the body of the `POST` request. Provide a unique string using your method of choice (such as a v4 UUID).\n\n\nIf a request is valid, Anchorage Digital will save the request indefinitely. If a subsequent request is received with the same `idempotentId` we will return the previously saved response for that `idempotentId`.\n\n\n# Rate Limits\n\n\nKeys provisioned by an Organization share one common rate limit. API requests are limited to 20 requests per second per Organization, allowing for bursts of up to 100 requests within a single second.\n\n\n# Pagination\n\n\nCursor pagination is used for REST endpoints which return multiple data points. Pagination allows for fetching data after the current page and specifying how many records to return. The `next` cursor is available in responses with the `page` attribute. Requests should use the `next` cursor URL to query subsequent data. Query parameter `afterId` specifies the last record previously retrieved. Some endpoints instead use the `endDate` parameter to specify the end date and older for records to retrieve. Query parameter `limit` specifies the maximum number of records in a response.\n\n## Parameters\n\n\n \n | Parameter | \n Description | \n
\n | afterId | \n Request page after (older than) this pagination id. | \n
\n \n | endDate | \n Request records older than this date (YYYY-MM-DD format). Used for /trading/trades and /trading/settlements resources. | \n
\n \n | limit | \n Maximum number of results requested. Default usually 25, but varies depending on resource. | \n
\n
\n\n## Example\n\n`GET /v2/transfers?afterId=1968b94b09b8a1a8a381775d1f04978c424d891d50e517774bf984297985b471&limit=100`\n\n## Next cursor\n\nThe `next` cursor is a URL which references the last record in a set of records. When queried, the `next` cursor URL will return subsequent records, but otherwise using the same query parameters."
servers:
- url: https://api.anchorage-staging.com/v2
security:
- Api-Access-Key: []
tags:
- description: 'These endpoints allow the organization to manage tax.
** UNDER DEVELOPMENT **
'
name: Tax
paths:
/tax/transactions/{subaccountId}:
get:
operationId: getTaxTransactions
summary: List Transactions
description: 'Permissions required: **Subaccount**
List tax transactions of a subaccount.
'
parameters:
- name: subaccountId
in: path
description: The ID of the subaccount
required: true
schema:
type: string
- name: startDate
in: query
description: The start date (inclusive) in `YYYY-MM-DD` format. The earliest valid start date is `2017-01-01`. The last valid start date is the current date. Dates are always in UTC [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) 'full-date'.
schema:
type: string
format: date
- name: endDate
in: query
description: The end date (inclusive) in `YYYY-MM-DD` format. The latest valid end date is the current date. Dates are always in UTC [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) 'full-date'.
schema:
type: string
format: date
responses:
'200':
description: Successfully returned list of transactions
content:
application/json:
schema:
$ref: '#/components/schemas/TaxTransactionsResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'401':
description: Unauthenticated
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'501':
description: Not Implemented Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
tags:
- Tax
x-security:
Subaccount: present
/tax/transaction/{transactionId}:
patch:
operationId: updateTaxTransaction
summary: Update Transaction Cost Basis
description: 'Permissions required: **Subaccount**
Update the cost basis for a deposit or withdraw transaction.
'
parameters:
- name: transactionId
in: path
description: The ID of the transaction to update (Same as the one returned for Transactions in the Subaccounts API )
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateTaxTransactionRequest'
responses:
'200':
description: Successfully updated the transaction
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateTaxTransactionResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'401':
description: Unauthenticated
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'501':
description: Not Implemented Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
tags:
- Tax
x-security:
Subaccount: present
/tax/transaction/{transactionId}/tag:
post:
operationId: tagTaxTransaction
summary: Add Tag to Transaction
description: 'Permissions required: **Subaccount**
Tag a prior transaction for tax purposes.
** Under development **
'
parameters:
- name: transactionId
in: path
description: The ID of the transaction to tag (Same as the one returned for Transactions in the Subaccounts API )
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TagTaxTransactionRequest'
responses:
'202':
description: Accepted tagging request
content:
application/json:
schema:
$ref: '#/components/schemas/TagTaxTransactionResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'401':
description: Unauthenticated
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'501':
description: Not Implemented Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
tags:
- Tax
x-security:
Subaccount: present
delete:
operationId: untagTaxTransaction
summary: Remove Tag from Transaction
description: 'Permissions required: **Subaccount**
Remove tax tag for a prior transaction.
** Under development **
'
parameters:
- name: transactionId
in: path
description: The ID of the transaction to tag (Same as the one returned for Transactions in the Subaccounts API )
required: true
schema:
type: string
- name: accountId
in: query
description: The subaccount for which the transaction happened.
required: true
schema:
type: string
example: SubaccountID
responses:
'202':
description: Accepted tag removal request
content:
application/json:
schema:
$ref: '#/components/schemas/UntagTaxTransactionResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'401':
description: Unauthenticated
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'501':
description: Not Implemented Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
tags:
- Tax
x-security:
Subaccount: present
/tax/inventory/{subaccountId}/{assetTypeId}:
get:
operationId: getTaxInventoryForAsset
summary: List of the Inventory for an asset
description: 'Permissions required: **Subaccount**
List user''s inventory for an asset.
'
parameters:
- name: subaccountId
in: path
description: The ID of the subaccount
required: true
schema:
type: string
- name: assetTypeId
in: path
description: Asset type identifier.
required: true
schema:
type: string
- name: limit
in: query
description: Number of results
schema:
type: integer
format: int64
default: 25
minimum: 0
- name: offset
in: query
description: Offset of the results to start
schema:
type: integer
format: int64
default: 0
minimum: 0
responses:
'200':
description: Successfully returned the inventory for an asset
content:
application/json:
schema:
$ref: '#/components/schemas/InventoryForAssetResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'401':
description: Unauthenticated
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'501':
description: Not Implemented Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
tags:
- Tax
x-security:
Subaccount: present
/tax/inventory/summary/{subaccountId}:
get:
operationId: getTaxInventorySummary
summary: List summary of Inventory
description: 'Permissions required: **Subaccount**
List user''s inventory summary for all assets.
'
parameters:
- name: subaccountId
in: path
description: The ID of the subaccount
required: true
schema:
type: string
- name: limit
in: query
description: Number of results
schema:
type: integer
format: int64
default: 25
minimum: 0
- name: offset
in: query
description: Offset of the results to start
schema:
type: integer
format: int64
default: 0
minimum: 0
responses:
'200':
description: Successfully returned the inventory summary
content:
application/json:
schema:
$ref: '#/components/schemas/InventorySummaryResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'401':
description: Unauthenticated
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'501':
description: Not Implemented Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
tags:
- Tax
x-security:
Subaccount: present
/tax/gains/costbasis/{subaccountId}:
get:
operationId: getTaxGainsCostBasis
summary: List Gains Cost Basis
description: 'Permissions required: **Subaccount**
List subaccount''s breakdown of combined cost basis, proceeds and gains/losses
'
parameters:
- name: subaccountId
in: path
description: The ID of the subaccount
required: true
schema:
type: string
- name: startDateTime
in: query
description: ISO-8601 formatted date as a filter start date.
required: true
schema:
type: string
format: date-time
- name: endDateTime
in: query
description: ISO-8601 formatted date as a filter end date.
required: true
schema:
type: string
format: date-time
responses:
'200':
description: Successfully returned the subaccount's tax gains cost bases
content:
application/json:
schema:
$ref: '#/components/schemas/TaxGainsCostBasisResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'401':
description: Unauthenticated
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'501':
description: Not Implemented Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
tags:
- Tax
x-security:
Subaccount: present
/tax/gains/summary/{subaccountId}:
get:
operationId: getTaxGains
summary: List Gains
description: 'Permissions required: **Subaccount**
List subaccount''s gains for a period breakdown to short term, long term and total
'
parameters:
- name: subaccountId
in: path
description: The ID of the subaccount
required: true
schema:
type: string
- name: startDateTime
in: query
description: ISO-8601 formatted date as a filter start date.
required: true
schema:
type: string
format: date-time
- name: endDateTime
in: query
description: ISO-8601 formatted date as a filter end date.
required: true
schema:
type: string
format: date-time
responses:
'200':
description: Successfully returned the gains
content:
application/json:
schema:
$ref: '#/components/schemas/TaxGainsResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'401':
description: Unauthenticated
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'501':
description: Not Implemented Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
tags:
- Tax
x-security:
Subaccount: present
/tax/subaccounts/{subaccountId}/forms:
get:
operationId: getSubaccountTaxForms
summary: Get Subaccount Tax Forms
description: 'Permissions required: **Subaccount**
Get subaccount''s generated tax forms
'
parameters:
- name: subaccountId
in: path
description: The ID of the subaccount
required: true
schema:
type: string
responses:
'200':
description: Successfully returned the forms
content:
application/json:
schema:
$ref: '#/components/schemas/TaxFormsResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'401':
description: Unauthenticated
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'501':
description: Not Implemented Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
tags:
- Tax
x-security:
Subaccount: present
/tax/clients/{customerId}/forms:
get:
operationId: getAffiliateTaxForms
summary: Get Program Customer Tax Forms
description: 'Permissions required: **Subaccount**
Get a program customer''s generated tax forms
'
parameters:
- name: customerId
in: path
description: The ID of the customer
required: true
schema:
type: string
responses:
'200':
description: Successfully returned the forms
content:
application/json:
schema:
$ref: '#/components/schemas/TaxFormsResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'401':
description: Unauthenticated
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
'501':
description: Not Implemented Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorDetails'
tags:
- Tax
x-security:
Subaccount: present
components:
schemas:
ErrorType:
description: The type of error returned.
type: string
enum:
- InternalError
- InvalidRequest
- Unauthenticated
- Forbidden
- NotFound
- Conflict
- UnprocessableEntity
- TooManyRequests
- ServiceUnavailable
- QuoteExpired
- InsufficientFunds
- NotImplemented
title: ErrorType
TaxForms:
description: Generated Tax Forms for a subaccount
type: object
properties:
forms:
description: Tax Forms generated for the specified subaccount
type: array
items:
$ref: '#/components/schemas/TaxFormItem'
example:
- formType: 1099B
downloadLink: URL_TO_USER
minItems: 0
uniqueItems: false
subaccountId:
description: ID for the subaccount for which the forms were generated
example:
subaccountId: ID
forms:
- createdDate: '2022-06-03T00:53:27.645Z'
id: doc-123e4567-e89b-12d3-a456-426614174000
revision: 1
revisionType: ORIGINAL
formType: 1099B
downloadLink: URL_TO_USER
year: 2023
isFiled: true
required:
- subaccountId
title: TaxForms
UpdateTaxTransactionResponseId:
type: object
properties:
transactionId:
description: The unique identifier of the transaction.
type: string
example: 9cd9f4d4-078b-4e44-a308-7662fec0f546
required:
- transactionId
title: UpdateTransactionResponseId
TaxTransaction:
description: Details of a transaction
type: object
properties:
externalId:
description: The unique identifier of the transaction in an external system orderID for trades and transactionID for deposits/withdraws
type: string
example: 9be748be-d760-4d36-90f8-86b699c4e8bd
fee:
$ref: '#/components/schemas/TaxTransactionCostBasis'
feeAsset:
description: The fee of the transaction, currently this is always in USD.
type: array
items:
$ref: '#/components/schemas/TaxTransactionCostBasis'
id:
description: The unique identifier of the transaction.
type: string
example: 9cd9f4d4-078b-4e44-a308-7662fec0f546
received:
$ref: '#/components/schemas/TaxTransactionCostBasis'
receivedAsset:
description: The received asset of a deposit transaction, or the bought asset of a trade transaction.
type: array
items:
$ref: '#/components/schemas/TaxTransactionCostBasis'
sent:
$ref: '#/components/schemas/TaxTransactionCostBasis'
sentAsset:
description: The sent asset of a withdraw transaction, or the sold asset of a trade transaction.
type: array
items:
$ref: '#/components/schemas/TaxTransactionCostBasis'
transactionTime:
description: ISO-8601 format date time when the transaction occurred.
type: string
format: date-time
example: '2022-07-30T22:15:31.99999Z'
type:
description: A string representing the type of the transaction.
type: string
example: DEPOSIT
enum:
- DEPOSIT
- WITHDRAW
- TRADE
required:
- id
- type
- transactionTime
title: Transaction
TaxFormsResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/TaxForms'
example:
- subaccountId: ID
forms:
- createdDate: '2022-06-03T00:53:27.645Z'
id: doc-123e4567-e89b-12d3-a456-426614174000
revision: 1
revisionType: ORIGINAL
formType: 1099B
downloadLink: URL_TO_USER
year: 2023
isFiled: true
minItems: 0
uniqueItems: false
required:
- data
title: TaxFormsResponse
InventorySummaryResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/InventorySummary'
example:
- assetType: BTC
quantity: '5.5'
costBasis: '2500.23'
- assetType: BTC
quantity: '53.5'
costBasis: '3600.23'
minItems: 0
uniqueItems: false
required:
- data
title: InventorySummaryResponse
TaxGainsAmount:
description: Summary of tax amount
type: object
properties:
assetType:
description: A string representing the asset type
type: string
example: USD
quantity:
description: Gain or loss quantity
type: string
example: '5.5'
required:
- assetType
- quantity
title: TaxGainsAmount
UpdateTaxTransactionRequest:
type: object
properties:
acquisitionDatetime:
description: ISO-8601 timestamp representing when the lot was acquired.
type: string
format: date-time
assetType:
description: A string representing the asset type of the transaction.
type: string
example: BTC
data:
$ref: '#/components/schemas/TaxTransactionCostBasis'
lots:
description: An Array of the Tax lots that are part of this transaction
type: array
items:
$ref: '#/components/schemas/TransactionTaxLot'
minItems: 1
uniqueItems: true
type:
description: A string representing the type of the transaction. Must match the original transaction type.
type: string
example: DEPOSIT
enum:
- DEPOSIT
- WITHDRAW
required:
- type
title: UpdateTransactionRequest
InventoryForAssetResponse:
type: object
properties:
data:
$ref: '#/components/schemas/InventoryForAsset'
title: InventoryForAssetResponse
InventoryTaxLots:
type: object
properties:
acquisitionDatetime:
description: ISO-8601 timestamp representing when the lot was acquired.
type: string
format: date-time
cost:
description: Cost basis of the lot. Will not Not appear if the lot is missing cost basis.
type: string
id:
description: Identifier for the Lot
type: string
quantity:
description: Amount of the Asset in the lot
type: string
unitCost:
description: Cost of a unit of the ASset within the lot. Will not appear if the lot doesn't have cost basis
type: string
title: InventoryTaxLots
TaxGainsCostBasisResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/TaxGainsCostBase'
example:
- sold:
assetType: BTC
quantity: '0.1'
proceeds:
assetType: USD
quantity: '300'
taxYear: '2023'
saleDate: '2022-06-30T22:15:31.99999Z'
gainType: LONG_TERM
gain:
assetType: USD
quantity: '20000'
cost:
assetType: USD
quantity: '305'
- sold:
assetType: ETH
quantity: '1'
proceeds:
assetType: USD
quantity: '1850'
taxYear: '2023'
saleDate: '2023-06-30T22:15:31.99999Z'
gainType: SHORT_TERM
gain:
assetType: USD
quantity: '150'
cost:
assetType: USD
quantity: '1880'
minItems: 0
uniqueItems: false
required:
- data
title: TaxGainsCostBasisResponse
TaxTransactionsResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/TaxTransaction'
example:
- id: 9cd9f4d4-078b-4e44-a308-7662fec0f546
type: DEPOSIT
transactionTime: '2022-07-30T22:15:31.99999Z'
received:
assetType: BTC
costBasis: '2500'
quantity: '1.0'
- id: 3459f4d4-078b-4e44-a308-7662fec0f546
type: WITHDRAW
transactionTime: '2022-07-30T22:15:31.99999Z'
sent:
assetType: BTC
costBasis: '2500'
quantity: '1.0'
- id: a2b4f4d4-078b-4e44-a308-7662fec0f546
type: TRADE
transactionTime: '2022-07-30T22:15:31.99999Z'
received:
assetType: USD
costBasis: '1'
quantity: '2500'
sent:
assetType: BTC
costBasis: '2500'
quantity: '1.0'
fee:
assetType: USD
costBasis: '1'
quantity: '0.01'
minItems: 0
uniqueItems: true
required:
- data
title: TransactionsResponse
TagTaxTransactionRequest:
type: object
properties:
accountId:
description: The subaccount for which the transaction happened.
type: string
example: SubaccountID
distributionCode:
description: 'IRS distribution code for Form 1099-R. Required when tag is ''distribution''.
Single codes:
- `1`: Early distribution, no known exception
- `2`: Early distribution, exception applies
- `3`: Disability
- `4`: Death
- `7`: Normal distribution
- `8`: Excess contributions plus earnings/excess deferrals taxable in current year
- `B`: Designated Roth account distribution
- `G`: Direct rollover and direct payment
- `H`: Direct rollover of a designated Roth account distribution to a Roth IRA
- `J`: Early distribution from a Roth IRA, no known exception
- `K`: Distribution of traditional IRA assets not having a readily available FMV
- `N`: Recharacterized IRA contribution made for current year
- `P`: Excess contributions plus earnings/excess deferrals taxable in prior year
- `Q`: Qualified distribution from a Roth IRA
- `R`: Recharacterized IRA contribution made for prior year
- `S`: Early distribution from a SIMPLE IRA in first 2 years, no known exception
- `T`: Roth IRA distribution, exception applies
Combination codes (two codes that apply to a single distribution):
`18`, `1B`, `1K`, `1P`, `28`, `2B`, `2K`, `2P`, `48`, `4B`, `4G`, `4H`, `4K`, `4P`, `6B`,
`7B`, `7K`, `81`, `82`, `84`, `8B`, `8J`, `8K`, `B1`, `B2`, `B4`, `B7`, `B8`, `BG`, `BL`,
`BP`, `G4`, `GB`, `GK`, `H4`, `J8`, `JP`, `K1`, `K2`, `K4`, `K7`, `K8`, `KG`, `LB`, `P1`,
`P2`, `P4`, `PB`, `PJ`'
type: string
example: '7'
enum:
- '1'
- '2'
- '3'
- '4'
- '7'
- '8'
- B
- G
- H
- J
- K
- N
- P
- Q
- R
- S
- T
- '18'
- 1B
- 1K
- 1P
- '28'
- 2B
- 2K
- 2P
- '48'
- 4B
- 4G
- 4H
- 4K
- 4P
- 6B
- 7B
- 7K
- '81'
- '82'
- '84'
- 8B
- 8J
- 8K
- B1
- B2
- B4
- B7
- B8
- BG
- BL
- BP
- G4
- GB
- GK
- H4
- J8
- JP
- K1
- K2
- K4
- K7
- K8
- KG
- LB
- P1
- P2
- P4
- PB
- PJ
postponedLateReason:
description: Reason for postponed contribution or late rollover. Required when tag is 'postponed' or 'late-rollover'.
type: string
example: qualified-disaster
tag:
description: Tag to be attributed to the transaction.
type: string
example: contribution
enum:
- contribution
- transfer-in
- conversion
- distribution
- transfer-out
- recharacterization
- late-rollover
- postponed
- rollover
taxYear:
description: The fiscal year the transaction belongs to.
type: string
example: '2024'
totalDistribution:
description: 'Deprecated: This field is ignored. Total distribution is now auto-computed from account balances.'
type: boolean
example: true
nullable: true
x-deprecated: true
title: UpdateTransactionRequest
TaxGainsCostBase:
description: Details of gains costs base
type: object
properties:
acquisitionTxId:
description: The unique identifier of the transaction where the asset was acquired in the tax system.
type: string
cost:
$ref: '#/components/schemas/TaxGainsAmount'
costBasisDate:
description: ISO-8601 format date time of the Cost Basis date
type: string
format: date-time
nullable: true
dispositionTxId:
description: The unique identifier of the transaction where the asset was sold in the tax system.
type: string
externalAcquisitionTxId:
description: The unique identifier of the transaction where the asset was acquired in the external system.
type: string
externalDispositionTxId:
description: The unique identifier of the transaction where the asset was sold in the external system.
type: string
gain:
$ref: '#/components/schemas/TaxGainsAmount'
gainType:
description: A string representing the gain type
type: string
example: LONG_TERM
enum:
- LONG_TERM
- SHORT_TERM
proceeds:
$ref: '#/components/schemas/TaxGainsAmount'
saleDate:
description: ISO-8601 format date time of the sale date
type: string
format: date-time
example: '2022-07-30T22:15:31.99999Z'
sold:
$ref: '#/components/schemas/TaxGainsAmount'
taxYear:
description: The tax year of the sale
type: string
example: '2023'
required:
- sold
- proceeds
- taxYear
- saleDate
- gainType
title: TaxGainsCostBase
TaxTransactionCostBasis:
description: Details of the transaction cost basis
type: object
properties:
assetType:
description: A string representing the asset type of the transaction.
type: string
example: BTC
costBasis:
description: The cost basis of the transaction.
type: string
example: '2500'
quantity:
description: The quantity of the transaction.
type: string
example: '1.0'
required:
- assetType
- quantity
title: TransactionCostBasis
TransactionTaxLot:
type: object
properties:
acquisitionDatetime:
description: ISO-8601 timestamp representing when the lot was acquired.
type: string
format: date-time
cost:
description: Cost basis of the lot. Will not Not appear if the lot is missing cost basis.
type: string
quantity:
description: Amount of the Asset in the lot
type: string
required:
- quantity
- cost
title: TransactionTaxLot
UntagTaxTransactionResponse:
type: object
properties:
data:
type: object
properties:
status:
description: The status of the tag removal request.
type: string
example: accepted
required:
- status
required:
- data
title: UntagTransactionResponse
TagTaxTransactionResponse:
type: object
properties:
data:
type: object
properties:
status:
description: The status of the tagging request.
type: string
example: accepted
required:
- status
required:
- data
title: TagTransactionResponse
ErrorDetails:
type: object
properties:
errorType:
$ref: '#/components/schemas/ErrorType'
message:
description: A human-readable message providing more details about the error.
type: string
example: Missing required field 'amount'.
required:
- errorType
- message
title: ErrorDetails
TaxFormItem:
description: Information about a generated tax form
type: object
properties:
createdDate:
description: ISO-8601 format date time when the tax form was created
type: string
format: date-time
example: '2022-06-03T00:53:27.645Z'
downloadLink:
description: A URL to download the generated tax form item
type: string
example: URL_TO_USER
formType:
description: The type of the generated tax form
type: string
example: 1099B
id:
description: The unique identifier of the tax form
type: string
example: doc-123e4567-e89b-12d3-a456-426614174000
isFiled:
description: Indicates whether the tax form has been filed
type: boolean
example: true
revision:
description: The revision number of the tax form
type: integer
format: int32
example: 1
revisionType:
description: The type of revision for the tax form
type: string
example: ORIGINAL
year:
description: The tax year for which the form was generated
type: integer
format: int32
example: 2023
required:
- formType
- downloadLink
title: TaxFormItem
InventorySummary:
description: Details of the inventory Summary
type: object
properties:
assetType:
description: A string representing the asset type
type: string
example: BTC
costBasis:
description: The cost basis of the asset.
type: string
example: '2500.23'
quantity:
description: Quantity of asset.
type: string
example: '5.5'
quantityWithCostBasis:
description: Quantity of an asset that has a cost basis associated.
type: string
example: '3'
quantityWithoutCostBasis:
description: Quantity of an asset that doesn't have a cost basis associated.
type: string
example: '2.5'
required:
- assetType
- costBasis
- quantity
title: InventorySummary
TaxGainsResponse:
type: object
properties:
data:
$ref: '#/components/schemas/TaxGains'
required:
- data
title: TaxGainsResponse
UpdateTaxTransactionResponse:
type: object
properties:
data:
$ref: '#/components/schemas/UpdateTaxTransactionResponseId'
required:
- data
title: UpdateTransactionResponse
TaxGains:
description: Breakdown of tax gains into short term, long term and total
type: object
properties:
longTerm:
$ref: '#/components/schemas/TaxGainsAmount'
shortTerm:
$ref: '#/components/schemas/TaxGainsAmount'
total:
$ref: '#/components/schemas/TaxGainsAmount'
example:
shortTerm:
assetType: USD
quantity: '20204.23'
longTerm:
assetType: USD
quantity: '200304.1'
total:
assetType: USD
quantity: '220308.33'
title: TaxGains
InventoryForAsset:
type: object
properties:
summary:
type: object
properties:
assetType:
description: Asset type identifier.
type: string
averageUnitCost:
description: Average cost of a unit of the Asset.
type: string
costBasis:
description: The cost basis of the asset.
type: string
example: '2500.23'
lots:
type: array
items:
$ref: '#/components/schemas/InventoryTaxLots'
quantity:
description: Quantity of asset.
type: string
example: '5.5'
totalQuantityMissingCostBasis:
description: Quantity of an asset that does not have a cost basis associated
type: string
example: '2.5'
totalQuantityWithCostBasis:
description: Quantity of an asset that has a cost basis associated
type: string
example: '3'
title: InventoryForAsset
securitySchemes:
Api-Access-Key:
type: apiKey
name: Api-Access-Key
in: header
description: An API key associated with a security role
x-tagGroups:
- name: Under Development
tags:
- Collateral Management
- Holds
- Deposit Attribution
- Onboarding
- Trusted Destinations
- Atlas Settlement Network
- Tax
- name: API Endpoints
tags:
- Addresses
- Asset Types
- Transactions
- Transfers
- Wallets
- Vaults
- Vesting
- Tagging
- Subaccounts
- Stablecoins
- Webhook Notifications
- API Key
- Statements
- Tax Reporting
- Trading
- name: Models
tags:
- Transfer Model
- Transaction Model
- Vault Model
- Deposit Attribution Model