The API lets you read and change almost anything in your Alsona account from your own code: agents, senders, prospects, inbox threads, templates, stats, and logs. If you want Alsona data inside a warehouse, a custom dashboard, or an internal tool, this is how you get it.
The full endpoint reference lives at api.alsona.com. This article covers getting started and the things the reference assumes you already know.
Before you reach for the API
Three options sit between you and writing code, and two of them are usually faster.
Option | Good for | Where it is |
Native integrations | Getting prospects and replies into a CRM you already use | Account menu, then Integrations. HubSpot also works as a prospect source. |
Webhooks | Reacting to something the moment it happens | Account menu, then Integrations, then Webhooks. Four events: LinkedIn invite accepted, profile invited, profile replied, email replied. |
The API | Pulling data on your own schedule, bulk changes, and anything the other two cannot do | Account menu, then Integrations, then API Integration. |
Webhooks push to you. The API lets you pull. Most working setups use both: a webhook to know something happened, then an API call to get the detail.
Step 1: Create an API key
Click your account name at the bottom left and choose Integrations.
Find the API Integration card and click Manage.
Give the key a name that says where it will be used, such as "Reporting warehouse" or "Zapier bridge". You will not remember "key 2" in six months.
Choose the permissions it needs. See the table below.
Leave the Enabled toggle on and click Generate key.
Copy the key immediately. Treat it like a password. Anyone holding it can do everything the scope allows, and there is no second factor in front of it.
Choosing permissions
Give each key the narrowest scope that lets it do its job. A reporting script does not need permission to delete agents.
Scope | Path it covers | Use it for |
All API (admin) | Everything, across the agency | Only when a single key genuinely needs full access. Avoid for anything running unattended. |
All | accounts/{account_id}/* | A key that manages one whole account. |
Campaigns | accounts/{account_id}/campaigns | Reading or changing agents and their prospects. |
Inbox | accounts/{account_id}/inbox | Reading conversations, syncing replies elsewhere. |
Integrations | accounts/{account_id}/integrations | Managing connected tools programmatically. |
Seats | accounts/{account_id}/seats | Reading sender status, connection counts, health. |
Step 2: Find your account ID
Your account ID is shown on the same API Keys screen, just below the key form, with a copy button next to it. It starts with ACCO. Every request path includes it.
Step 3: Make your first request
The base URL is:
Authenticate with an X-API-KEY header. There is no OAuth flow and no bearer token.
This lists the agents on an account:
-H "X-API-KEY: <your key>"
And this returns the account itself:
-H "X-API-KEY: <your key>"
{
"success": true,
"account": {
"account_id": "ACCOXXXXXXXXXXXXXXXXXXXX",
"agency_id": "AGENXXXXXXXXXXXXXXXXXXXX",
"name": "My Account",
"active_until": "2026-03-20",
"seats_free": 5,
"seats_paid": 3,
"seats_used": 3,
"status": "ENABLED",
"created_at": 1748275405332,
"created_by": "john.doe@example.com"
}
}
The vocabulary gap, and why it matters
This is the part that trips people up, so it is worth stating plainly rather than leaving you to work it out from a 404.
The API uses the old names. What the interface calls an agent, the API calls a campaign. What the interface calls a sender, the API calls a seat. The paths, the fields, and the ID prefixes all follow the API's vocabulary, not the interface's.
In the interface | In the API | Looks like |
Agent | campaign | accounts/{account_id}/campaigns, campaign_id, CAMP… |
Sender | seat | accounts/{account_id}/seats, seat_id, SEAT… |
Account | account | account_id, ACCO… |
Agency | agency | agency_id, AGEN… |
Prospects on an agent | campaign profiles | campaign-profiles endpoints |
You will also see this inside the product. Open any agent and look at the URL: the ID starts with CAMP. That is the same identifier the API expects, so you can copy an agent ID straight out of your address bar and use it in a request.
Reading responses
Every response is JSON and every response carries a success field.
{ "success": true, "campaigns": [ ... ] }
When something goes wrong, success is false and message explains why.
{
"success": false,
"message": "Missing or invalid API key"
}
Check success rather than only checking the status code. It is the more reliable signal and it is present on every response.
Response codes
Code | Status | What it usually means |
200 | Success | The request worked. |
400 | Bad Request | The path or parameters are invalid. Check for a missing or malformed account ID. |
401 | Unauthorized | Missing or invalid API key, or the key has no access to this account. Check the header name is exactly X-API-KEY. |
403 | Forbidden | The key is valid but its scope does not cover this endpoint or method. A Seats-scoped key calling a campaigns endpoint gets this. |
404 | Not Found | The resource or route does not exist. Often a campaign ID that has been deleted, or an endpoint path typo. |
500 | Internal Server Error | Something failed on our side. Retry, and contact support if it persists. |
The difference between 401 and 403 is worth remembering. A 401 means the key is wrong. A 403 means the key is right but does not have the permission you gave it, which usually means you scoped it too narrowly when you created it.
Pagination
List endpoints are cursor-based rather than page-numbered. Each response includes a count and a last_key.
Make your first request with no last_key.
If last_key comes back non-null, URL-encode it and pass it as a query parameter on your next request.
Repeat until last_key comes back null. At that point you have everything.
-H "X-API-KEY: <your key>"
Do not treat count as a total. It is the number of records in that response, not the number that exist.
Account keys and agency keys
An account key reaches one account.
An agency key reaches accounts across your agency, but it does not aggregate. You still name one account per request.
For agencies this is the single most common misunderstanding: an agency key does not give you one call that returns every client's data. To report across ten clients you loop through ten account IDs. Use the agency endpoint to list your accounts, then iterate.
What you can reach
The full reference at api.alsona.com documents every endpoint. In outline:
Resource | What you can do | Typical use |
Account, Agency | Read | Seat counts, subscription status, listing the accounts under an agency. |
Campaigns (agents) | Create, read, update, delete, list | Pausing agents in bulk, cloning a proven setup, auditing what is running. |
Campaign profiles | Create, read, update, delete, list | Pulling prospects out to a warehouse, pushing a list in. |
Filters | Create, read, update, delete, list | Managing targeting programmatically. |
Integrations | Create, read, update, delete, list | Managing connected tools without using the interface. |
Inbox, email and LinkedIn | List, read, update, delete threads and messages | Syncing conversations into a CRM or helpdesk. The LinkedIn side can also generate an AI response. |
Seats (senders) | Read, list | Monitoring sender status and connection counts across a fleet. |
Stats | Read, including a last-24-hours call | Feeding a dashboard without scraping the interface. |
Templates | Create, read, update, delete, list | Version-controlling message copy outside Alsona. |
Logs | Read, list | Debugging why an agent did or did not do something. |
Three things people build first
A reporting pull
Hit the stats endpoint on a schedule, one call per account, and write the result to a warehouse. This is the most common use and the easiest. Scope the key to a single account, read-only in practice, and run it nightly.
Replies into a CRM or helpdesk
Subscribe to the "profile replied" and "email replied" webhooks, then call the inbox endpoints to fetch the thread when one fires. The webhook tells you something happened, the API tells you what was said.
A fleet health check
List seats across every account each morning and alert on any whose status is not ENABLED. For agencies running dozens of senders, a disconnected sender that nobody notices for three days is expensive.
Keeping keys safe
One key per system. Shared keys cannot be revoked without breaking everything at once.
Scope narrowly. Most keys need one resource, not All API (admin).
Never put a key in front-end code, a public repository, or a shared document. Anyone who reads it has your access.
Disable rather than delete while you investigate. The Enabled toggle on the keys screen turns a key off without destroying it, which is what you want when you are not yet sure whether it is the one that leaked.
Rotate on a schedule and whenever someone with access leaves.
If a request is not working
Check the header name is exactly X-API-KEY. Case matters in some clients.
Check you are using the account ID and not the agency ID. Both are shown in the interface and they look similar.
Check you are using campaigns rather than agents in the path. This is the most common 404.
If you get a 403, look at the key's scope. It is a permission problem, not a key problem.
Check the Logs endpoints. They often explain agent behaviour faster than reading the interface.
The full reference
Every endpoint, with parameters and example responses, is documented at api.alsona.com. Start at the introduction page for authentication and pagination, and use the API Reference section for individual endpoints.
