API reference
A8 Core™ — the operating system for financial accounts — exposes account, client, financial, and reporting operations as a JSON API over HTTPS. This reference documents the request and response contract for each operation.
Production API base URL
A8 Core™ documentation and developer resources are published on a8core.com. API requests are transmitted to the A8 Core™ web service at api.a8core.io. All v1 endpoint paths shown in this documentation are relative to https://api.a8core.io/v1.
Service families
Every operation in this reference belongs to one of five service families. The family tells you what a call does to the record; the method and path tell you which record.
Create
Create Client, Account and Asset records.
Manage
Manage existing Client, Account and Asset records.
Update
Update existing Client, Account and Asset records.
Financial
Deposit and send funds to and from a client account by ACH or card.
Utility
Administrative APIs for operating A8 Core.
Authentication
Every request is authenticated with a hash-based message authentication code (HMAC). Build a canonical base from the method, URL, timestamp and JSON body, sign it with your shared secret using HMAC-SHA256, and pass the result in the Authorization header as HMAC keyId:signature:timestamp. Requests without a valid signature are rejected.
Content-Type: application/json Authorization: HMAC key_live_8fa2c1e4:9f86d081884c7d65...:1782925451
Conventions
A few patterns hold across the entire API:
Field naming & identifiers
Field names use PascalCase. Resource identifiers — ClientId, AccountId — are Guid values. Reference IDs you supply (such as ProviderReferenceId) are free-form strings scoped to your provider.
The response envelope
Operations return a consistent envelope: a RequestId that identifies the call, and a Status indicating the outcome. Resource operations add the resulting identifier (e.g. AccountId).
RequestId is a 13-digit long; log it on your side so any call can be traced end to end through the platform’s audit log.
Idempotency, pagination & errors
A few conventions apply to every operation. Following them keeps integrations safe to retry and easy to debug.
Idempotency
Send a stable ProviderReferenceId on every POST that creates or moves money (Fund Account, Transact, Create Client). A8 Core™ treats a repeated ProviderReferenceId from the same provider as the same operation, so a retried request never double-applies.
Pagination
List operations accept PageNumber and PageSize and return a TotalCount alongside the records, so you can page deterministically.
Errors
Every response carries the standard envelope. On a handled application error the call still returns HTTP 200 with Status = 0 and a ResponseStatus object describing the failure; transport, authentication, and signature failures return a non-2xx HTTP status.
"RequestId": 1736472902501, "Status": 0, "ResponseStatus": { "ErrorCode": "ClientNotFound", "Message": "No client matches the supplied ClientId." }
Create Account
Opens a new A8 Core™ account of a given type for an existing client, optionally linked to a sponsor investment.
Request
| Name | Type | Description | |
|---|---|---|---|
| ProviderReferenceId | string | optional | Your internal reference ID for the account being created. |
| ClientId | Guid | required | The A8 Core™ Client ID the account belongs to. |
| AccountTypeCode | string | required | Account type slug, e.g. roth-ira. Required parameters vary by nature — see the type’s own page. |
| InstitutionId | Guid | conditional | Required for CustodialHolding, PlanHolding, and DepositLiability. |
| TrusteeId | Guid | conditional | Required for PlanHolding (ERISA § 403(a)). |
| InvestmentId | long | optional | Links the account to a specific sponsor investment. |
Response
| Name | Type | Description |
|---|---|---|
| RequestId | long | 13-digit ID for the API request that was made. |
| Status | int | Outcome of the request: 1 for pass, 0 for fail. |
| AccountId | Guid | The newly created A8 Core™ Account ID. |
Example request
"ProviderReferenceId": "acct-10293", "ClientId": "8fa2c1e4-5b6d-4f3a-9c2e-7d1a2b3c4d5e", "AccountTypeCode": "roth-ira", "InstitutionId": "b4c1e770-9d33-4a02-91ef-2c6a8b5d0f14", "InvestmentId": 84217
Example response
"RequestId": 1736472901835, "Status": 1, "AccountId": "3c7b1f90-2a44-4e21-8d6c-9b0e5a1f7c22"
Account types
A8 Core™ does not have one kind of account. It has five natures, distinguished by who holds title and who owes what to whom. Nature is a type, not a column.
Pass the slug as AccountTypeCode on Create Account. Each type below has its own reference page with required parameters, a worked example, error codes, and the rules that govern it.
CustodialHolding — Beneficial owner holds title; the institution holds possession. Off balance sheet.
PlanHolding — Assets held in trust under a plan. A named trustee is required.
BenefitObligation — No assets. An employer obligation and a claims ledger.
DepositLiability — The institution owes the customer money. On balance sheet. May go negative.
ServicingRecord — Recorded, not held. No assets and no obligation.
PlanHolding.TrusteeId is non-nullable. A BenefitObligation holds no securities, so it does not implement IHoldsAssets. A deposit is a liability of the institution, not a holding of the customer — so DepositLiability has no holdings collection and its balance may go negative.
Availability is computed, not declared
Every account type declares the authorities an institution must hold before it may open one. Within a requirement group, any one authority satisfies it. Across groups, all must be satisfied.
| Authority | Legal basis | |
|---|---|---|
| IrsNonbankCustodian | Treas. Reg. § 1.408-2(e). Scoped by asset class in the approval letter. | |
| Bank | 12 U.S.C. § 1813(a), or a state bank charter. For IRAs, § 408(n). | |
| StateTrustCompany | State trust charter with fiduciary powers. | |
| InsuredDepositoryInstitution | 12 U.S.C. § 1813(c). The only authority that permits taking deposits. | |
| HsaTrusteeOrCustodian | I.R.C. § 223(d)(1)(B): a bank, an insurance company, or an IRS-approved nonbank trustee. | |
| EsaTrusteeOrCustodian | I.R.C. § 530(b)(1)(B). | |
| TrumpAccountTrustee | A § 408(n) bank, or an IRS-approved nonbank trustee of a Trump account. An entity approved as an IRA nonbank trustee on or before 2025-12-31 is automatically approved, but must notify the IRS under Treas. Reg. § 1.408-2(e)(6)(iv). Notice 2025-68 Q&A A-3. | |
| TreasuryFinancialAgent | Selected by Treasury under I.R.C. § 530A(g) to serve as trustee of INITIAL Trump accounts. Rollover Trump account trustees are not subject to this selection. | |
| ErisaTrustee | ERISA § 403(a). Capacity to hold plan assets in trust. | |
| BrokerDealer | Exchange Act § 15(b) registration. | |
| QualifiedCustodianAdvisersAct | Advisers Act Rule 206(4)-2(d)(6). Not implied by any other authority. | |
| StateQtpServicingAgreement | Contract with a State qualified tuition program. I.R.C. § 529(b)(1). | |
| PermittedPaymentStablecoinCustodian | GENIUS Act, Pub. L. 119-27. Supervised entities only. | |
available = institution satisfies the type's authority requirements ∩ provider is contracted for the type ∩ type status is shippable, or the gate is satisfied
Call GET https://api.a8core.io/v1/account-types to resolve it. The directory above is the superset the platform supports, not the list any one institution may offer.
TaxType is gone. It hid two independent facts: whether a contribution is deductible, and how earnings are taxed. A Trump account has mixed contribution treatment with tax-deferred earnings. No single value could say that.
Get Account
Request
| Name | Type | Description | |
|---|---|---|---|
| AccountId | Guid | required | The A8 Core™ Account ID, supplied as a path parameter. |
Response
| Name | Type | Description |
|---|---|---|
| RequestId | long | 13-digit ID for the API request that was made. |
| Status | int | Outcome of the request: 1 for pass, 0 for fail. |
| AccountId | Guid | The A8 Core™ Account ID. |
| AccountNumber | string | The account number. |
| ClientId | Guid | The client the account belongs to. |
| AccountTypeCode | string | Account type slug. |
| Phase | string | Standard, GrowthPeriod, PostGrowth, or InheritedDistribution. |
| AccountStatus | string | Current account status. |
| EstablishedDate | datetime | When the account was established. |
| AccountBalance | AccountBalance | Available and settled balance. |
Example request
GET https://api.a8core.io/v1/accounts/3c7b1f90-2a44-4e21-8d6c-9b0e5a1f7c22
Example response
"RequestId": 1736472901835, "Status": 1, "AccountId": "3c7b1f90-2a44-4e21-8d6c-9b0e5a1f7c22", "AccountNumber": "100023481", "AccountTypeCode": "roth-ira", "Phase": "Standard", "AccountStatus": "Active"
Update Account
Request
| Name | Type | Description | |
|---|---|---|---|
| AccountId | Guid | required | The A8 Core™ Account ID, supplied as a path parameter. |
| ProviderReferenceId | string | optional | Your internal reference for the account. |
| AccountStatus | string | optional | New account status. |
Response
| Name | Type | Description |
|---|---|---|
| RequestId | long | 13-digit ID for the API request that was made. |
| Status | int | Outcome of the request: 1 for pass, 0 for fail. |
| AccountId | Guid | The updated A8 Core™ Account ID. |
Example request
"ProviderReferenceId": "acct-10293-v2", "AccountStatus": "Active"
Example response
"RequestId": 1736472901922, "Status": 1, "AccountId": "3c7b1f90-2a44-4e21-8d6c-9b0e5a1f7c22"
Create Client
Request
| Name | Type | Description | |
|---|---|---|---|
| ProviderReferenceId | string | optional | Your internal reference for the client. |
| ClientType | string | required | The client type, e.g. Individual or Entity. |
| Contact | Contact | required | Name and contact details for the client. |
| SponsorId | Guid | optional | Links the client to a sponsor. |
| OFAC | OFACInfo | optional | Optional OFAC screening information. |
Response
| Name | Type | Description |
|---|---|---|
| RequestId | long | 13-digit ID for the API request that was made. |
| Status | int | Outcome of the request: 1 for pass, 0 for fail. |
| ClientId | Guid | The newly created A8 Core™ Client ID. |
Example request
"ProviderReferenceId": "cli-55021", "ClientType": "Individual", "Contact": { "FirstName": "Jordan", "LastName": "Rivera" }
Example response
"RequestId": 1736472902004, "Status": 1, "ClientId": "8fa2c1e4-5b6d-4f3a-9c2e-7d1a2b3c4d5e"
Get Client
Request
| Name | Type | Description | |
|---|---|---|---|
| ClientId | Guid | required | The A8 Core™ Client ID, supplied as a path parameter. |
Response
| Name | Type | Description |
|---|---|---|
| RequestId | long | 13-digit ID for the API request that was made. |
| Status | int | Outcome of the request: 1 for pass, 0 for fail. |
| ClientId | Guid | The A8 Core™ Client ID. |
| ClientNumber | string | The client number. |
| ClientType | string | The client type. |
| Contact | Contact | Client contact details. |
| ClientStatus | string | Current client status. |
| CreatedDate | datetime | When the client was created. |
Example request
GET https://api.a8core.io/v1/clients/8fa2c1e4-5b6d-4f3a-9c2e-7d1a2b3c4d5e
Example response
"RequestId": 1736472902110, "Status": 1, "ClientId": "8fa2c1e4-5b6d-4f3a-9c2e-7d1a2b3c4d5e", "ClientType": "Individual", "ClientStatus": "Active"
Fund Account
Request
| Name | Type | Description | |
|---|---|---|---|
| AccountId | Guid | required | The account to fund, supplied as a path parameter. |
| Amount | decimal | required | The deposit amount. |
| Currency | string | required | ISO currency code, e.g. USD. |
| PaymentMethodType | string | required | How the deposit is made, e.g. ECheck. |
| TaxYear | int | optional | Validated against the type’s ContributionYearRule. A Trump account is CalendarYearOnly: there is no prior-year election. |
| PlanYear | int | conditional | Required for BenefitObligation. |
| ContributionSource | string | conditional | Required for a Trump account. Drives both cap participation and basis. |
| ProviderReferenceId | string | optional | Your reference; used as the idempotency key. |
Response
| Name | Type | Description |
|---|---|---|
| RequestId | long | 13-digit ID for the API request that was made. |
| Status | int | Outcome of the request: 1 for pass, 0 for fail. |
| TransactionId | Guid | The resulting transaction ID. |
Example request
"Amount": 5000.00, "Currency": "USD", "PaymentMethodType": "ECheck", "TaxYear": 2026, "ProviderReferenceId": "fund-90233"
Example response
"RequestId": 1736472902255, "Status": 1, "TransactionId": "d99c0a31-7e0b-4a18-9f55-1c2d3e4f5a01"
Transact
Request
| Name | Type | Description | |
|---|---|---|---|
| AccountId | Guid | required | The account to transact against, supplied as a path parameter. |
| EntryType | string | required | The transaction entry type, e.g. Fee or Distribution. |
| Amount | decimal | required | The transaction amount. |
| Currency | string | required | ISO currency code, e.g. USD. |
| PaymentMethodType | string | optional | Payment method, where applicable. |
| Description | string | optional | Free-form description. |
| ProviderReferenceId | string | optional | Your reference; used as the idempotency key. |
Response
| Name | Type | Description |
|---|---|---|
| RequestId | long | 13-digit ID for the API request that was made. |
| Status | int | Outcome of the request: 1 for pass, 0 for fail. |
| TransactionId | Guid | The resulting transaction ID. |
Example request
"EntryType": "Distribution", "Amount": 1200.00, "Currency": "USD", "Description": "Q2 scheduled distribution", "ProviderReferenceId": "txn-44120"
Example response
"RequestId": 1736472902390, "Status": 1, "TransactionId": "a71b9c20-3d44-4e55-8c66-9b0e5a1f7c33"
Webhooks
A8 Core™ pushes account, client, and financial events to your endpoints as signed webhooks, so you react to activity without polling.
You register one HTTPS endpoint per event type. When the event fires, A8 Core™ POSTs a signed JSON envelope to your URL. Every delivery is signed per RFC 9421 HTTP Message Signatures, so you verify authenticity before acting.
Event catalog
| Event | Fires when |
|---|---|
account.created | An account was opened. |
account.updated | An account’s details or status changed. |
client.created | A client was created. |
client.updated | A client’s details or status changed. |
deposit.posted | A deposit directive posted to an account. |
withdrawal.posted | A withdrawal directive posted. |
transfer.completed | A transfer directive completed. |
rollover.completed | A rollover directive completed. |
investment.purchased | An investment purchase directive completed. |
investment.sold | An investment sale directive completed. |
Neither event fires for a BenefitObligation or a DepositLiability. Both reject investment directives with ErrorCode: "AccountTypeNotInvestable". | |
recharacterization.completed | A recharacterization directive completed. |
rothconversion.completed | A Roth conversion directive completed. |
Delivery payload
Signature-Input: sig1=("@authority" "content-digest");created=1782925451;keyid="a8core-ed25519-2026a";alg="ed25519" Signature: sig1=:k8r2...c1Qe: "EventId": "e51b7c44-9a02-4c18-bb31-77a0d2e9f410", "EventType": "deposit.posted", "OccurredAt": "2026-08-01T17:04:11Z", "Data": { "AccountId": "3c7b1f90-...", "TransactionId": "d99c0a31-...", "Amount": 5000.00, "Status": "Posted" }
Verifying a delivery
Webhook signatures follow RFC 9421. The Signature-Input header carries the covered components, a created timestamp, a keyid, and the alg; the Signature header carries the signature bytes. You choose the algorithm when you register an endpoint:
| alg | Model | How you verify |
|---|---|---|
hmac-sha256 | Shared secret (default) | Recompute the HMAC-SHA256 over the signing base with your secret and compare in constant time. |
ed25519 | Asymmetric (recommended for third-party endpoints) | Verify the signature against A8 Core™’s published Ed25519 public key. There is no shared secret to leak, so a compromise on your side cannot forge A8 Core™ deliveries. |
Both algorithms are registered in RFC 9421. Fetch the current Ed25519 public keys (with their keyids) from the webhook signing keys endpoint; keys rotate, so resolve by keyid rather than pinning one. Also confirm created and the payload’s OccurredAt are recent to guard against replay. Signing proves authenticity and integrity — it does not encrypt — so always receive over TLS.
Webhook signing keys
When you verify with ed25519, check deliveries against A8 Core™’s published public keys. Keys are served as a JWKS document and rotate on a rolling schedule, with the old and new key both valid during an overlap window. Resolve the key by the keyid carried in the delivery’s Signature-Input rather than pinning a single key, and cache the set with a short TTL.
"keys": [ { "kty": "OKP", "crv": "Ed25519", "use": "sig", "alg": "EdDSA", "kid": "a8core-ed25519-2026a", "x": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo" }, { "kty": "OKP", "crv": "Ed25519", "use": "sig", "alg": "EdDSA", "kid": "a8core-ed25519-2026b", "x": "kPrK_qmxVWaYVA9wwBF6Iuo3vVzz7TxHCTwXBygrS4k" } ]
hmac-sha256 endpoints verify with the shared secret set at registration and do not use this endpoint. Host and path shown are illustrative; confirm them against your deployment.
Delivery & retries
Acknowledge with any 2xx promptly and do heavier work asynchronously. Non-2xx or timeouts are retried with exponential backoff for up to 24 hours. Deliveries may repeat, so make consumers idempotent by de-duplicating on EventId.
More operations
The platform exposes the full account lifecycle — beneficiaries, investments, transfers, rollovers, recharacterizations, Roth conversions, IRS forms, and required minimum distributions — all following the authentication, idempotency, and response-envelope conventions documented above. See Asset classes for what each account may hold. Request API access for the complete operation set.
Asset classes
A holding is described on four orthogonal axes. Overloading one field with all four is what produced an enum in which Cash, RealEstate, and Brokerage were siblings.
| Axis | Question it answers | Example |
|---|---|---|
| AssetClass | What kind of thing is this, to an investor? | RealEstate |
| InstrumentType | What is it, legally? | TaxLiens |
| CustodyModel | How is possession actually held? | ContractualOnly |
| ValuationMethod | How is fair market value established? | IndependentAppraisal |
The ten classes
Eligibility
The matrix is the account-type dimension only. What an account may hold is the intersection of the account-type rule, the asset-class rule, any instrument predicates, and the institution’s authority asset scope. Approval to hold publicly traded securities is not approval to hold real estate.
| Account family | Stocks & ETFs | Mutual funds | Bonds & fixed income | Cash & money market | Real estate | Private equity & venture | Private credit & notes | Precious metals | Digital assets | Stablecoins |
|---|---|---|---|---|---|---|---|---|---|---|
| IRA — not self-directedtraditional-ira roth-ira sep-ira simple-ira | Permitted | Permitted | Permitted | Permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted |
| IRA — self-directed+ SelfDirected capability | Permitted | Permitted | Permitted | Permitted | Conditional | Conditional | Conditional | Conditional | Conditional | Conditional |
| Inherited IRAinherited-traditional-ira inherited-roth-ira | Permitted | Permitted | Permitted | Permitted | Conditional | Conditional | Conditional | Conditional | Conditional | Conditional |
| Trump account — growth periodtrump-account-initial trump-account-rollover | Conditional | Conditional | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted |
| Trump account — after growth periodsame accounts, phase = PostGrowth | Permitted | Permitted | Permitted | Permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted |
| Automatic Rollover IRAautomatic-rollover-ira | Not permitted | Conditional | Not permitted | Permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted |
| Solo 401(k)solo-401k-* | Permitted | Permitted | Permitted | Permitted | Conditional | Conditional | Conditional | Conditional | Conditional | Conditional |
| Profit-sharing / ESOPprofit-sharing-plan employee-stock-ownership-plan | Permitted | Permitted | Permitted | Permitted | Conditional | Conditional | Conditional | Conditional | Conditional | Conditional |
| Coverdell ESAcoverdell-esa | Permitted | Permitted | Permitted | Permitted | Conditional | Conditional | Conditional | Not permitted | Conditional | Conditional |
| Health Savings Accounthealth-savings-account | Permitted | Permitted | Permitted | Permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted |
| Emergency Savings — PLESAemergency-savings-plesa | Not permitted | Not permitted | Not permitted | Permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted |
| Emergency Savings — taxableemergency-savings-taxable | Not permitted | Conditional | Not permitted | Permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted |
| FSA · HRA · LSA · commuter · COBRABenefitObligation | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted |
| Demand deposit · MMDA · time depositDepositLiability | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable |
| Taxable brokeragetaxable-brokerage | Permitted | Permitted | Permitted | Permitted | Permitted | Permitted | Permitted | Permitted | Conditional | Conditional |
| Trustrevocable-trust irrevocable-trust | Permitted | Permitted | Permitted | Permitted | Permitted | Permitted | Permitted | Permitted | Conditional | Conditional |
| 1031 exchange escrow1031-exchange-escrow | Not permitted | Not permitted | Not permitted | Permitted | Conditional | Not permitted | Not permitted | Not permitted | Not permitted | Not permitted |
| Private fund custodyprivate-fund-custody | Not permitted | Not permitted | Not permitted | Permitted | Not permitted | Permitted | Permitted | Not permitted | Not permitted | Not permitted |
| 529 servicing529-servicing | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable |
| Stablecoinstablecoin-account | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable | Not applicable |
Collectible or LifeInsurance instrument type — reject the asset rather than mapping it to Other.A8 Core™ is a directed, non-discretionary recordkeeper. Availability of an instrument type is not a determination that it is suitable, prudent, or lawful for any account.