Contacts API
POST /api/v1/contacts/{id}/brief
Has the AI read a contact's timeline and return a summary, an engagement score, a recommended next action and a draft message. The brief is saved on the contact, and the score is copied onto the contact so lists and automations can use it. Requires the write:contacts scope.
POST /api/v1/contacts/cmq2cont0alk34567890/brief HTTP/1.1
Host: agentlyleads.com
Authorization: Bearer alk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
{ "asUserEmail": "kevin@example.com" }The path accepts the agentlyleads ID or your externalId. The body is optional: asUserEmail records which workspace member the brief was generated for, and defaults to the workspace owner.
Response (201)
{
"brief": {
"id": "cmq2brf00alk34567890",
"contactId": "cmq2cont0alk34567890",
"summary": "Bought two pallets in March, asked about bulk pricing in August and has not heard back.",
"engagementScore": 72,
"recommendedAction": "Send the bulk price sheet and offer a call this week.",
"draftMessage": "Hi Ann, following up on bulk pricing...",
"profileSuggestions": [{ "field": "title", "value": "Purchasing manager", "reason": "Signs her emails that way." }],
"model": "gpt-4.1-mini",
"generatedAt": "2026-09-27T15:04:00.000Z"
}
}profileSuggestions are fields the brief noticed in the timeline that the contact record leaves empty. They are never applied automatically.
Billing
Each call is one AI action, the same as generating a brief in the app:
- It counts against the workspace's monthly AI allowance. When that is used up the response is
402with the date it resets. - If the workspace has its own AI key for briefs, the call runs on that key and does not count against the allowance.
| Status | When |
|---|---|
402 | The workspace has used its AI actions for the month |
404 | No contact with that ID in your workspace |
502 | The AI provider failed, or rejected the workspace's own key (the message says which and where to fix it) |