AdviceCloud API
Use the Firm API to read and change your firm's investment settings: risk levels, the allocations of asset classes and security categories, security category mappings, and minimum trade sizes. Each request acts on the firm of the person who approved the access token.
The /reports domain API: the performance reports of your firm's
households and accounts, the report batches that make them, the report
templates that save a set of report options, and your firm's activity
log.
The /models domain API: your firm's models, the target portfolios that
you assign to households and accounts, and the sleeves, security groups
and benchmarks that models use. It also calculates the performance,
asset allocation and risk allocation of a portfolio before you save it
as a model.
The /billing domain API: your firm's billing reports and their
finalize workflows, the fee structures, billing minimums and asset
exclusions that set how fees are calculated, the billing splits that
send part of a fee to a splitter, the fee estimates of a household, and
the cash settings of your firm and of each of its accounts.
The /rebalances domain API: the rebalances of your firm's households,
which the console calls trade proposals, the rebalance boards that save
a filter of the rebalance list, the transactions of your firm's
accounts, the forecasted transfers of cash in and out of those accounts,
and the securities that trades and holdings name.
The Client domain API: your firm's households, accounts and contacts, the holdings, performance and allocation of each household and account, their notes, tasks and workflows in your firm's CRM, the household and contact data connections that link them to CRM records, the accounts assigned to each household, the required minimum distributions (RMDs) of your households with their RMD profiles, RMD annual records, distributions and distribution ledgers, the firm RMD summary, and search across your firm's records.
Base URL
All requests go to this base URL:
https://app.advicecloudft.com/api
Add the path of an operation to the base URL. For example, List risk
levels is GET /v1/firm/risk, so the request goes to
https://app.advicecloudft.com/api/v1/firm/risk.
Versions
The major version is part of every path, such as /v1. Every operation in
this document is under /v1. Always include the version: a path without
it is not part of this API.
Each domain API, such as the Firm API, has its own version and is deprecated on its own schedule.
AdviceCloud makes a breaking change only in a new version of a domain API. Breaking changes include:
- removing or renaming a field
- narrowing a type
- changing a status code
- changing the meaning of an existing parameter
Within a version, AdviceCloud can add optional fields and optional parameters. Write your code to ignore fields it does not recognize.
Authentication
The API uses the OAuth 2.0 device authorization grant. Your script asks for a code, a person approves the code in a browser, and your script receives tokens that act with that person's firm, role and scopes.
- Request a device code from the issuer host. Send the
client_id, the script audience and the scopes you need, such asoffline_access read:firm. The response contains adevice_code, auser_codeand averification_uri. - Show the code and the address to the person. The person opens the address on any device with a browser and signs in with their AdviceCloud login. The person must belong to a firm in AdviceCloud.
- The consent page names "AdviceCloud API" and lists the scopes. The person approves only a code that they started themselves.
- Poll the token endpoint on the issuer host with the grant type
urn:ietf:params:oauth:grant-type:device_code. After the person approves, the response contains an access token, valid for 3600 seconds, and a refresh token. A request for any audience other than the script audience is refused. - Call the API with the access token as a bearer token in the
Authorizationheader. The token works only for operations that require a scope it carries. Other routes that require a token return403. - When the access token expires, use the refresh token to get a new one. Each refresh also returns a new refresh token. The person does not need to do anything.
Refresh tokens
- Save the new refresh token before you use the new access token.
- Use one approval in each process. If two processes share one token file, the approval ends.
- Never send a refresh token that was already used: the approval ends. A retry after a network error can send a used refresh token by accident.
When the person must approve again
The refresh fails, and the person repeats step 2, in each of these cases:
- 30 days pass with no refresh
- 90 days pass in total
- your script sends a refresh token that was already used
- AdviceCloud revokes the approval
Example
$ISSUER_HOST, $CLIENT_ID and $SCRIPT_AUDIENCE are the issuer host,
the client_id of the "AdviceCloud API" client and the identifier of the
script audience. The security scheme scriptAccess states whether they
are published. Use the issuer host exactly as published: a token from a
different host gets 401. $API_ROOT is the base URL.
# 1. Start. Show verification_uri_complete, or verification_uri and user_code, to the person.
curl -s -X POST "https://$ISSUER_HOST/oauth/device/code" \
-d client_id="$CLIENT_ID" -d audience="$SCRIPT_AUDIENCE" \
-d scope="offline_access read:firm"
# 2. Poll every `interval` seconds until the person approves.
# Save refresh_token before you use access_token.
curl -s -X POST "https://$ISSUER_HOST/oauth/token" \
-d grant_type="urn:ietf:params:oauth:grant-type:device_code" \
-d device_code="$DEVICE_CODE" -d client_id="$CLIENT_ID"
# 3. Call the API.
curl -s "$API_ROOT/v1/firm/risk" -H "Authorization: Bearer $ACCESS_TOKEN"
# 4. Renew. Save the new refresh_token before you use the new access_token.
# Never send the old refresh_token again: the approval then ends.
curl -s -X POST "https://$ISSUER_HOST/oauth/token" \
-d grant_type=refresh_token -d client_id="$CLIENT_ID" -d refresh_token="$REFRESH_TOKEN"
Scopes
The public API has a read: and a write: scope for each of the six
domain APIs, and also read:search.
All of them are listed here.
In this release, every operation requires one scope on the bearer token:
the read: scope of its domain API for a GET, and the write: scope of
its domain API for any other method, except where a path is named below
with a scope of its own. The scopes of each domain API this release
publishes:
- Firm:
read:firmandwrite:firm /reports:read:reportandwrite:report- Models:
read:modelandwrite:model /billing:read:billingandwrite:billing/rebalances:read:rebalanceandwrite:rebalance- Client:
read:householdandwrite:household; every operation on/v1/searchrequiresread:search
Each scope covers the paths that start with the prefixes listed after it, and no others:
read:household:/households,/accounts,/contacts,/rmdwrite:household:/households,/accounts,/contacts,/rmdread:firm:/firm,/users,/profilewrite:firm:/firm,/users,/profileread:model:/modelswrite:model:/modelsread:billing:/billing,/cash-settingswrite:billing:/billing,/cash-settingsread:report:/reports,/insights,/dashboard,/activity-logwrite:report:/reports,/insights,/dashboard,/activity-logread:rebalance:/rebalances,/transactions,/transfers,/securitieswrite:rebalance:/rebalances,/transactions,/transfers,/securitiesread:search:/searchread:crm:/households,/contacts,/searchwrite:crm:/households,/contacts
The scopes of the Client domain API are read:household and
write:household.
read:crm and write:crm give access to your firm's households, contacts
and notes, and read:crm also to search. On the paths listed for each, an
operation accepts read:crm in place of the scope it requires for a GET,
except GET /v1/households/custom-fields, and write:crm in place of the
scope it requires for any other method. A token needs only one of the scopes
that an operation accepts.
Pagination
An operation that returns a list returns it one page at a time. Choose the page with two query parameters:
limit: maximum number of items to return. Default50. There is no upper limit.offset: number of items to skip before the first one returned. Default0.
A limit or offset that is not a whole number, or a limit less than
1, returns 400. The API does not replace an invalid value with the
default.
The response has a pagination object beside data. It gives the limit
and offset of the page, and totalCount, the number of items in the
whole collection:
{
"data": [ ... ],
"pagination": { "limit": 50, "offset": 0, "totalCount": 137 }
}
To get every item, send the request again with offset increased by
limit, until offset is totalCount or more.
Items can be skipped or repeated if the collection changes while you page through it. The API has no cursor, and it cannot tell you when this happens.
Errors
Every error response has the same JSON body:
{
"statusCode": 400,
"message": "One sentence that a person can read.",
"details": { ... }
}
statusCode: HTTP status code of the response, as a number.message: description of the error, for a person to read.details: object with more information about the error. Present only for some errors. Ignore keys you do not recognize.
You can read statusCode and message the same way for every operation.
Status codes:
400: the request is invalid, for example a query parameter or the request body fails validation. If more than one check fails,messagegives each cause, separated by;.401: the access token is missing, invalid, or expired, or a different issuer host issued it.403: the access token is valid, but it does not have the scope that the operation requires, or the person's role does not allow the operation.404: no operation matches the method and path, or the operation documents404for an ID that your firm does not have. Each operation states what it returns for an ID that does not exist.429: too many requests. See Rate limit.500: an error in AdviceCloud. The body is{ "statusCode": 500, "message": "Internal server error" }.
A 500 on the first call after the approval. This status is not a
temporary fault. Do not retry the call. The API returns 500 when the
person who approved the code does not belong to a firm in AdviceCloud, and
a retry does not change that.
Rate limit
The API counts each request against one of two rate limits. A request over
its limit returns 429.
Per person. A request whose access token is for the script audience
counts against the person who approved the token:
30 requests per 10 seconds per person per API instance, across all
operations. The request counts after the token is accepted and before the
scope is checked, so a request that returns 403 counts, and a request
that returns 401 does not. Over this limit, the response has a
Retry-After-per-person header with the number of seconds to wait.
Per client IP address. Every other request counts against its client
IP address: 60 requests per 10 seconds from one client IP address to one
operation. Each operation has its own count, which all requests from that
address share. The request counts before the token is checked, so a
request that returns 401 counts too. Over this limit, the response has a
Retry-After header with the number of seconds to wait.
Each API instance counts on its own. The counts are not shared between instances. Your requests are spread across the instances that are running, so the limit you see can be up to the instance count times higher than the figures above, and you cannot see or choose which instance answers a request. Treat each figure as the limit that always applies, not as a quota to use up.
Deprecation
AdviceCloud announces the removal of a published operation, or a breaking change to it, before the change. The minimum notice period is 90 days. The 90 days count from the first publication of the version that is deprecated, not from the announcement.
An announcement uses each of these channels:
- the
Deprecationresponse header on the deprecated operation deprecated: trueon the operation in this document- an entry in the changelog
- an email to each customer of the domain API
No operation of version 1 is deprecated, so no response has the
Deprecation header.
Changes and revisions
The changelog lists each change to this document. One changelog covers every domain API, and each entry names the domain API and the version it applies to.
- To read in a browser:
https://app.advicecloudft.com/api/openapi/changelog - As JSON:
https://app.advicecloudft.com/api/openapi/changelog.json
AdviceCloud adds to a version while it is served, so this document can
change within a version. Each revision of the document is identified by
the date it was first published, in the form YYYY-MM-DD, with a -N
suffix when more than one revision was published that day.
This document is revision 2026-09-24-2, at:
https://app.advicecloudft.com/api/openapi/revisions/2026-09-24-2.json
An earlier revision is at the same address, with its own identifier in place of this one. A revision stays available while any version it describes is served. The changelog lists the revisions that are kept.
Authentication
- OAuth 2.0: scriptAccess
OAuth 2.0 device authorization grant (RFC 8628). Your script shows a short user code and a verification address to a person. The person opens the address on any device with a browser, signs in, and approves the code. The access token acts for that person, with their firm, role and scopes. See Authentication.
The grant types, urn:ietf:params:oauth:grant-type:device_code and
refresh_token, are in x-grant-types. The scopes are in the scopes
map of the x-deviceCode flow.
An access token is valid for 3600 seconds. Each refresh returns a new
refresh token. A refresh token expires after 30 days (2592000 seconds)
with no use, and after 90 days (7776000 seconds) in total. Request the
offline_access scope to receive a refresh token.
These values are not yet published: the issuer host, the device authorization address, the token address, the client id of "AdviceCloud API" and the identifier of the script audience.
x-audiences lists the audiences that this API accepts in the aud
claim of a token; a token with any other aud is refused. This scheme
does not describe the audience of the MCP server, which uses a
different audience.
Security Scheme Type: | oauth2 |
|---|---|
OAuth Flow (x-deviceCode): | Scopes:
|