Updated
Before you start
- An API key: in Coolie, open Settings → API keys, name the key and click Create key. It is shown once, so keep it in an environment variable (
COOLIE_API_KEYin these examples). It acts as you, with your plan, your credits and your agents. - A Coolie account with its 7-day free trial started: the API answers 402 trial_required before that. A call costs what the same action costs in the app, and nothing more.
- A free agent on your plan: creating one uses one of your plan's agents (403 agent_quota once they are all in use).
Pick the signals
GET /api/v1/signals lists the buying signals an agent can watch. Use the ids whose available is true: a signal held back, or without a source connected right now, is refused.
curl https://trycoolie.ai/api/v1/signals \
-H "Authorization: Bearer $COOLIE_API_KEY"{
"signals": [
{
"id": "hiring",
"name": "Hiring",
"description": "Companies actively hiring, to find the right profiles",
"available": true
},
{
"id": "competitor-churn",
"name": "Competitor Churn",
"description": "Find companies that recently churned from your competitors",
"available": true
}
]
}Pick the ICP's values
Industries, locations and company sizes must be values of GET /api/v1/icp-options: anything else is refused with 400 invalid_icp_value. A location may also be one of the regions it lists (Europe, North America, Latin America, Asia-Pacific, Middle East, Africa, DACH, Nordics), which stands for its countries. Job titles are free text, at least one: they say whom to contact at each company.
curl https://trycoolie.ai/api/v1/icp-options \
-H "Authorization: Bearer $COOLIE_API_KEY"Create the agent
POST the body: the agent is saved, active, and its first search starts at once.
curl https://trycoolie.ai/api/v1/agents \
-H "Authorization: Bearer $COOLIE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Ops leaders at hospitals in France",
"icp": {
"jobTitles": [
"COO",
"Head of Operations"
],
"industries": [
"Hospitals and Health Care"
],
"locations": [
"France"
],
"companySizes": [
"201-500 employees",
"501-1000 employees"
],
"keywordsInclude": [],
"keywordsExclude": [],
"mode": "broad"
},
"signalEventIds": [
"hiring",
"funding",
"recent-job-change"
],
"signalConfigs": {
"hiring": {
"jobTitles": [
"Operations Manager"
]
}
},
"findEmail": true,
"findPhone": false
}'import os
import requests
API = "https://trycoolie.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['COOLIE_API_KEY']}"}
body = {
"name": "Ops leaders at hospitals in France",
"icp": {
"jobTitles": ["COO", "Head of Operations"],
"industries": ["Hospitals and Health Care"],
"locations": ["France"],
"companySizes": ["201-500 employees", "501-1000 employees"],
"keywordsInclude": [],
"keywordsExclude": [],
"mode": "broad",
},
"signalEventIds": ["hiring", "funding", "recent-job-change"],
"signalConfigs": {
"hiring": {
"jobTitles": ["Operations Manager"],
},
},
"findEmail": True,
"findPhone": False,
}
response = requests.post(f"{API}/agents", json=body, headers=HEADERS, timeout=60)
if response.status_code >= 400:
error = response.json()
raise SystemExit(f"{response.status_code} {error['error']}: {error['message']}")
created = response.json()
print("Agent", created["agentId"], "is running its first search, run", created["runId"])const response = await fetch("https://trycoolie.ai/api/v1/agents", {
method: "POST",
headers: {
Authorization: "Bearer " + process.env.COOLIE_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": "Ops leaders at hospitals in France",
"icp": {
"jobTitles": [
"COO",
"Head of Operations"
],
"industries": [
"Hospitals and Health Care"
],
"locations": [
"France"
],
"companySizes": [
"201-500 employees",
"501-1000 employees"
],
"keywordsInclude": [],
"keywordsExclude": [],
"mode": "broad"
},
"signalEventIds": [
"hiring",
"funding",
"recent-job-change"
],
"signalConfigs": {
"hiring": {
"jobTitles": [
"Operations Manager"
]
}
},
"findEmail": true,
"findPhone": false
}),
});
const data = await response.json();
if (!response.ok) throw new Error(response.status + " " + data.error + ": " + data.message);
console.log("Agent " + data.agentId + " is running its first search");signalConfigs is optional: here it tells the Hiring signal which job postings count. Competitor Churn and Competitor Renewal take competitors, Tech Used technologies, Buying Intent Topic topics, five values each at most.
Follow its first search
The first search runs one signal now; the others take turns, one search every three hours, up to your plan's daily leads. GET /api/v1/agents/{agentId} says what each search found and when the next one runs, in fields and in one sentence, activity.summary. The leads arrive at GET /api/v1/agents/{agentId}/leads.
curl https://trycoolie.ai/api/v1/agents/agent-3f2a91c0 \
-H "Authorization: Bearer $COOLIE_API_KEY"{
"agent": {
"id": "agent-3f2a91c0",
"name": "Ops leaders at hospitals in France",
"status": "active",
"createdAt": "2026-10-19T08:59:58.120Z",
"icp": {
"jobTitles": [
"COO",
"Head of Operations"
],
"industries": [
"Hospitals and Health Care"
],
"locations": [
"France"
],
"companySizes": [
"201-500 employees",
"501-1000 employees"
],
"keywordsInclude": [],
"keywordsExclude": [],
"mode": "broad"
},
"signalEventIds": [
"hiring",
"funding",
"recent-job-change"
],
"signalConfigs": {
"hiring": {
"jobTitles": [
"Operations Manager"
],
"jobDescriptionKeywords": [],
"employmentTypes": [],
"seniorities": []
}
},
"findEmail": true,
"findPhone": false,
"sequenceConfig": null,
"autoWritePerDay": 0,
"activity": {
"leads": {
"total": 3,
"today": 3
},
"lastSearches": [
{
"at": "2026-10-19T09:00:04.000Z",
"running": false,
"newLeads": 3,
"title": "3 new leads",
"signals": [
{
"signal": "hiring",
"name": "Hiring",
"text": "8 results, 4 new companies: 3 leads."
}
],
"note": null
}
],
"nextSearchAt": "2026-10-19T12:00:00.000Z",
"summary": "Its last search (5 minutes ago) brought 3 new leads. 3 leads so far, 3 today. Next search in 2 h 55 min."
}
}
}The rules a body follows
- Three to five signals, and at least three searches a day: Hiring, Tech Used, Buying Intent Topic and Competitor Churn search once per value of their list (job titles, technologies, topics, competitors), the other signals once each (400 too_few_searches).
- Five values at most in each signal's list.
modebroad accepts adjacent company sizes; specific does not.- Ten agents created through the API a day per account at most (429 agent_create_limit), and your plan's agents in all (403 agent_quota).
- A running agent's targeting is locked:
POST /api/v1/agents/{agentId}/stopbefore aPATCH /api/v1/agents/{agentId}that changes it (409 agent_running).
What POST /api/v1/agents answers
The new agent's id, and the id of the run its first search is. The values are examples.
{
"agentId": "agent-3f2a91c0",
"runId": "ui-5b9e2c41"
}Errors
An error answers with its HTTP status and a body { "error": code, "message": sentence }: branch on the code, show or log the message.
| Status | Code | What to do |
|---|---|---|
| 400 | invalid_body | A field is missing or wrong; message names it (for example icp.jobTitles, or fewer than 3 signals). |
| 400 | invalid_icp_value | An industry, location or company size is not in GET /api/v1/icp-options. |
| 400 | signal_coming_soon | A signal is not offered yet: GET /api/v1/signals says which are. |
| 400 | signal_not_live | A signal has no source connected right now; the answer's signals field names it. |
| 400 | too_few_searches | The agent would make fewer than three searches a day: add signals, or values to them. |
| 402 | trial_required | Start the free trial in the app first. |
| 403 | agent_quota | Your plan's agents are all in use: delete one, or add one in Settings → Billing. |
| 429 | agent_create_limit | Ten agents created through the API today already; Retry-After says when the UTC day ends. |
| 401 | missing_api_key | No key in the request: send Authorization: Bearer coolie_sk_… or an x-api-key header. |
| 401 | invalid_api_key | Not a Coolie key, or a key that is unknown or revoked: copy it again from Settings → API keys. |
| 429 | rate_limited | More than 60 requests in the minute for your account: wait the seconds Retry-After gives, then try again. |
Frequently asked questions
How many signals can a Coolie agent watch?
Three to five. Hiring, Tech Used, Buying Intent Topic and Competitor Churn search once per value of their list, up to five values, the others once each, so an agent makes between three and twenty-five searches a day.
Does creating an agent cost credits?
It uses one of your plan's agents. Reading its leads costs nothing; credits pay for what you ask for on a lead, such as an email found (0.1 credit) or research (1 credit).
Can I change an agent after creating it?
Yes: PATCH /api/v1/agents/{agentId} with the fields to change, or status active or paused. Stop a running agent first if you change its targeting.
How do I pause or delete an agent?
POST /api/v1/agents/{agentId}/pause pauses it and /start switches it on again. DELETE /api/v1/agents/{agentId} deletes it with its leads, which cannot be undone.
Can an AI assistant create agents for me?
Yes, through Coolie's MCP server: connect Claude or ChatGPT and describe the market in plain words.
Every endpoint, field and error is in the API reference, and more guides are in the developer hub.
