readyDocs Open the appOpen the app

Sub-accounts

For agencies running one Ready account per customer. Each sub-account has its own numbers and registration, and pays for its own texts with its own card and balance unless you create it with billing: "agency". Call these with an rsms_ key from your own account, and act inside a sub-account with X-Sub-Account-Id. Set a sub-account’s prices with partner fees. The API can’t remove a sub-account: in the app, open it under Sub-accounts and choose Remove sub-account. That deletes its contacts, conversations and call logs, so export them first with GET /contacts/export and GET /sms/export, sending X-Sub-Account-Id.

#Set up a sub-account

  1. POST /v1/sub-accounts creates the sub-account.
  2. Register its brand with Register, sending X-Sub-Account-Id.
  3. POST /v1/team-members gives a person a login.
  4. Optional, approved partners only: set their prices with Partner fees.

To list your sub-accounts with sends, replies, spend and registration, call GET /v1/partner/clients. It works for every agency, with or without the Partner program; the name is historical.

The API has no call to remove a sub-account. To remove one, open Sub-accounts in the dashboard and choose Remove sub-account. You pick what happens to its numbers first.

#The Sub-account object

idinteger
The sub-account’s id, the same number as its Ready ID in the app. Send it as X-Sub-Account-Id.
emailstring
The sub-account owner’s email.
first_name, last_namestring
The owner’s name. Not in the create response.
company_namestring
The sub-account’s business name.
statusstring
The sub-account’s status, for example active. Not in the create response.
account_kindstring
client for a sub-account with an owner, workspace for one you run yourself with no owner email. A sub-account you pay for (billing: "agency", Me in the app’s Add sub-account dialog) is either one: see Sub-accounts.
billingstring
Who pays. Possible values: client, agency.
created_atstring
When the sub-account was made, ISO 8601. Not in the create response.
shares_owner_capacityboolean or null
Whether the sub-account texts under your registration while it has none of its own. null for a sub-account that pays for itself: it never texts under yours. Not in the create response.
shared_daily_limitinteger or null
How many texts a day, on all carriers, it may send under your registration. null means no limit of its own. Not in the create response.
client_ratenull
Only in the create response, and always null: a new sub-account starts at Ready’s price, with no markup.
invite_linkstring
Only in the create response. The sub-account’s sign-in link, to send yourself when send_invite is false.
Legacy fields (2)
kindstring
The older name for account_kind, same value. It still works. Not in the create response.
markup_usd_per_segmentnumber or null
The sub-account’s legacy per-segment markup, in dollars, or null when it has none. It can only be removed (Older paths). Not in the create response.

#Create a sub-account

Creates a sub-account with its own login, card, numbers and registration. Needs the Manage team permission (invite_team).

Parameters

emailstringRequired unless billing is agency
The sub-account owner’s email. Leave it out only with billing: "agency", which makes a sub-account you run yourself; that create answers 201 with id, company_name, ownerless: true, account_kind and invite_email_sent, without invite_link or client_rate (Sub-accounts).
first_name, last_namestring
company_namestring
company_name is required when email is left out.
send_invitebooleanDefault true
Emails the sub-account an invite to set up their login and card. Send false to skip the email and send them invite_link yourself.
billingstringDefault client
client: the sub-account adds their own card and pays their own bill. agency: your card pays for the sub-account’s registration, numbers and messages, at your prices. The API has no call to change it later.

Returns a Sub-account object in data.

Errors
HTTPCodeWhen
400invalid_requestMissing email unless billing is agency, or missing company_name when email is left out.
400unknown_fieldA field it doesn’t accept.
403agency_onlyYour account is another agency’s sub-account. Use your main account’s key.
409client_already_yoursAlready your sub-account. Find its id with List sub-accounts.
409email_has_accountThat email already has its own account. Contact support to link it.
409email_reservedEmail can’t be used (403 for a staff address).

#List sub-accounts

The sub-accounts you manage, and your own business accounts, newest first. Pages with a cursor. Needs the Manage team permission (invite_team).

Parameters

limitinteger · queryDefault 50Max 200
Page size.
before_idinteger · query
The next_before_id from the previous page.

Returns a list of Sub-account objects in data.

Returns
has_moreboolean
true when another page follows. Keep paging while it’s true.
next_before_idinteger | null
Pass as before_id.

#Get a sub-account

One sub-account, as the list returns it, including your own business accounts (account_kind workspace). Needs the Manage team permission (invite_team).

Parameters

idinteger · pathRequired
The sub-account id.

Returns a Sub-account object in data.

Errors
HTTPCodeWhen
404sub_account_not_foundNot a sub-account you manage.

#Set capacity sharing

These two settings choose whether a sub-account texts under your registration, and how many texts a day it may send there. We count 4 in 10 of its daily limit against your T-Mobile daily cap, since about 1 in 3 US phones is on T-Mobile. Once its own registration is approved, it texts under that one instead and the limit no longer applies. Needs the Manage team permission (invite_team).

Parameters

idinteger · pathRequired
The sub-account id.
shares_owner_capacityboolean
false stops it texting under your registration. Until its own registration is approved, it can’t send.
shared_daily_limitinteger or null
Texts a day on all carriers, from 1 to 10,000,000. null or 0 removes the limit. Texts past the limit are refused with DAILY_CAP_REACHED until the next day.

Send at least one of the two. Returns the updated Sub-account object in data.

Errors
HTTPCodeWhen
400invalid_requestNeither field was sent, or a value is the wrong type or out of range.
403organization_onlyThe key’s user has Organization only access, so it can’t change a sub-account.
404sub_account_not_foundNot a sub-account you manage.
409not_a_sharing_sub_accountThe sub-account pays for itself, so it never texts under your registration.

#Give a sub-account a setup

Installs a snapshot into a sub-account: its templates, drip campaigns, automations, campaigns, lists, custom fields and contact pipelines, matched by name so nothing is added twice. Automations arrive off, and drip campaigns and campaigns arrive as drafts. Make a snapshot with Create a snapshot, and find its key with List your snapshots. Needs the Campaigns permission (manage_campaigns). In the app, a sub-account’s page has a Snapshot card that installs one.

Parameters

X-Sub-Account-Idinteger · header
The sub-account to install it into. Leave it out to install into your own account.
keystringRequired
The snapshot’s share key.
Returns

Counts of what was added, such as automations_created, templates_created, drips_created, campaigns_created, pipelines_created and stages_added. Running it again adds nothing. items lists each thing added with its kind (a drip campaign is sequence), and refused lists the kinds our content checks turned away (campaign, template, drip). Moving a phone number between accounts is Move a number to a sub-account.

Errors
HTTPCodeWhen
400invalid_requestkey is missing.
400OWN_SNAPSHOTYou made this snapshot, so its setup is already in your account.
403permission_deniedKey lacks manage_campaigns.
404SNAPSHOT_NOT_FOUNDNo snapshot has that key. Check it with List your snapshots.
500SNAPSHOT_DAMAGEDThe snapshot can’t be read. Make a new snapshot and use its key.
500IMPORT_PARTIALSome items were added and data.failed lists the kinds that were not. Send the same request again: nothing is added twice.
500 / 503IMPORT_RETRYNothing was installed. Send it again in a minute.

#List your snapshots

The snapshots your account made, newest first, with the share key Give a sub-account a setup takes. Needs the Campaigns permission (manage_campaigns).

Returns
data[]object[]
key (the share key), label, url (the share link), apply_count (how many times it was installed), created_at and counts (automations, templates, drips, campaigns, pipelines).
Errors
HTTPCodeWhen
403permission_deniedThe key’s user can’t manage campaigns.
500request_failedThe list couldn’t be read. Retry.

#Create a snapshot

Packs the items you pick into a new snapshot and gives back its share key. It reads only your own items and changes nothing in the account. Sending it again makes a second snapshot with a new key. Needs the Campaigns permission (manage_campaigns).

Parameters

labelstringDefault My setup
A name for it, up to 80 characters.
accountinteger
Take the items from this sub-account instead of your own account. The snapshot is still yours.
automations, templates, drips, campaignsinteger[]
The ids of the items to include. Pick at least one item in all.
pipelinesstring[]
The contact pipelines to include, by id.

Returns data.key, data.label, data.url and data.counts.

Errors
HTTPCodeWhen
400invalid_request, unknown_fieldA field of the wrong type, or one it doesn’t accept.
400request_failedNothing picked, or none of the picked items are on the account.
403request_failedaccount isn’t one of your accounts.
403permission_deniedThe key’s user can’t manage campaigns.
500request_failedNo snapshot was made. Retry.

#Move a number to a sub-account

Gives a number your account holds to one of your own sub-accounts. It can text from it right away, and you keep paying for it. Call forwarding on the number is turned off, and its caller ID name is removed; the sub-account can set its own. To take it back, call Unassign a number (POST /v1/numbers/:id/unassign). If the sub-account has its own approved registration with room, the number moves onto it.

A sub-account that pays for itself buys or ports its own numbers, so it answers 404.

Path parameters

idintegerRequired
The number id.

Body parameters

sub_account_idintegerRequired
The sub-account to give it to.
Errors
HTTPCodeWhen
400invalid_fieldsub_account_id is missing.
400SUB_ACCOUNT_REQUIREDsub_account_id is not an id.
403permission_deniedKey lacks manage_phones.
404NUMBER_NOT_FOUNDThe number isn’t yours. A second call on a number already moved answers 404.
404sub_account_not_foundThe sub-account isn’t one of yours, or it pays for itself and buys its own numbers.
409NUMBER_ASSIGN_BLOCKEDThis number can’t be moved; reason says why.
500ASSIGN_NOT_APPLIEDNothing moved. Check GET /v1/numbers/:id and send it again.
500MOVE_UNCONFIRMEDCheck GET /v1/numbers/:id before trying again.
Older paths

PUT /v1/sub-accounts/:id/rate: only clears a sub-account’s legacy markup. Send {"markup": 0}, or {"use_default": true} when your default markup is 0. Needs the Manage team permission (invite_team). A sub-account that already pays a markup keeps paying it until you remove it, and you can’t add it back: use partner fees instead. Returns data.markup, data.is_custom, data.base_rate (your rate) and data.client_rate (null means Ready’s standard price).

  • 400 markup_retired: a markup above 0, or use_default with a default above 0.
  • 400 invalid_request: a negative markup, or nothing to change. 400 unknown_field: a field it doesn’t accept.
  • 403 forbidden: not your main account. 404 sub_account_not_found: not a sub-account you manage. 409 rate_locked: contact support.
  • dialer_markup and use_default_dialer (a call markup) are saved. A sub-account you bill pays this markup on each billed call minute. Above 0 they can be refused with terms_required, reseller_not_approved, forbidden, or invalid_markup above $0.06.