For Coding Agents
AGNT Contacts
Why AGNT Contacts
Your agents need to know who they're talking to. Not just an email address — the full picture. Name, company, timezone, every email alias they've ever used.
AGNT Contacts gives your agents a structured contact book that stays in sync with your users. Import contacts in bulk, merge duplicates, and let the platform automatically link contacts to registered users when they show up. No manual reconciliation. No stale data.
Every contact belongs to a user context. Your agent sees the same contact list as the human it's acting for.
Quick Start
1. Create a Contact
curl -X POST https://api.agnt.ai/contacts \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": "jane@acme.co",
"name": "Jane Chen",
"company": "Acme Corp",
"title": "VP Engineering",
"timezone": "America/Los_Angeles"
}'{
"ok": true,
"contact": {
"id": "cnt_abc123",
"user": "usr_def456",
"account": "acc_ghi789",
"email": "jane@acme.co",
"name": "Jane Chen",
"phone": null,
"company": "Acme Corp",
"title": "VP Engineering",
"timezone": "America/Los_Angeles",
"emails": ["jane@acme.co"],
"consumer": null,
"status": "active",
"createdAt": "2026-03-01T12:00:00.000Z",
"updatedAt": "2026-03-01T12:00:00.000Z"
}
}2. Bulk Import
curl -X POST https://api.agnt.ai/contacts/bulk-import \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"contacts": [
{ "email": "jane@acme.co", "name": "Jane Chen", "company": "Acme Corp" },
{ "email": "bob@widgets.io", "name": "Bob Park", "timezone": "America/New_York" },
{ "email": "sara@example.com", "name": "Sara Lee" }
]
}'{
"ok": true,
"total": 3,
"created": 2,
"updated": 1,
"skipped": 0,
"errors": []
}3. List Contacts
curl https://api.agnt.ai/contacts?search=acme&page=1&perPage=20 \
-H "Authorization: Bearer $TOKEN"Core Concepts
Contact Identity
Every contact is identified by email. It's the uniqueness key. When you create or import a contact with an email that already exists for that user, the existing record is updated instead of duplicated.
A contact can have multiple email addresses in the emails[] array. The primary email field is the canonical one. Additional addresses are merged in over time as you update the contact or import new data.
User Linking
When a contact's email matches a registered AGNT user, the platform automatically links them via the consumer field. This happens at creation and during bulk import. No API call needed — the link is established silently.
This means your agent can look at a contact and immediately know whether that person is also a user on your platform.
Merging
Two contacts that turn out to be the same person? Merge them. The merge operation combines email arrays, preserves the target contact, and removes the source. All references update automatically.
Bulk Import
The bulk import endpoint handles up to 1,000 contacts per request. For each contact in the batch:
- If the email is new, a contact is created
- If the email exists, the existing contact is updated with any new fields
- If a matching AGNT user is found, the contact is automatically linked
- Malformed entries are skipped and reported in the
errors[]array
This is idempotent. Run the same import twice and nothing changes the second time.
API Reference
Endpoints
| Method | Path | Description | Auth |
|---|---|---|---|
GET | /contacts | List contacts | Delegated |
POST | /contacts | Create a contact | Delegated |
POST | /contacts/bulk-import | Bulk import up to 1,000 contacts | Delegated |
GET | /contacts/:contactId | Get a contact | Delegated |
PUT | /contacts/:contactId | Update a contact | Delegated |
DELETE | /contacts/:contactId | Delete a contact | Delegated |
POST | /contacts/:contactId/merge | Merge two contacts | Delegated |
GET | /users/:userId/contacts | List contacts for a specific user | Delegated |
Contact Object
{
"id": "cnt_abc123",
"user": "usr_def456",
"account": "acc_ghi789",
"email": "jane@acme.co",
"name": "Jane Chen",
"phone": "+1-555-0123",
"company": "Acme Corp",
"title": "VP Engineering",
"timezone": "America/Los_Angeles",
"emails": ["jane@acme.co", "jchen@acme.co"],
"consumer": "usr_xyz999",
"status": "active",
"createdAt": "2026-03-01T12:00:00.000Z",
"updatedAt": "2026-03-01T14:30:00.000Z"
}| Field | Type | Description |
|---|---|---|
id | string | Unique contact ID |
user | string | ID of the user who owns this contact |
account | string | Account ID |
email | string | Primary email address (uniqueness key) |
name | string | Full name |
phone | string | Phone number |
company | string | Company name |
title | string | Job title |
timezone | string | IANA timezone (e.g., America/New_York) |
emails | string[] | All known email addresses for this contact |
consumer | string | null | Linked AGNT user ID, if the contact is a registered user |
status | string | Contact status (active) |
createdAt | string | ISO 8601 creation timestamp |
updatedAt | string | ISO 8601 last update timestamp |
List Contacts
GET https://api.agnt.ai/contacts
| Parameter | Type | Description |
|---|---|---|
userId | string | Filter by user ID |
status | string | Filter by status |
search | string | Search by name, email, or company |
page | number | Page number (default: 1) |
perPage | number | Results per page (default: 20) |
{
"ok": true,
"contacts": [
{ "id": "cnt_abc123", "email": "jane@acme.co", "name": "Jane Chen", "..." : "..." },
{ "id": "cnt_def456", "email": "bob@widgets.io", "name": "Bob Park", "..." : "..." }
],
"page": 1,
"perPage": 20,
"total": 2
}Create Contact
POST https://api.agnt.ai/contacts
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Primary email address |
name | string | No | Full name |
phone | string | No | Phone number |
company | string | No | Company name |
title | string | No | Job title |
timezone | string | No | IANA timezone |
consumerEmail | string | No | Email of an existing AGNT user to link |
Bulk Import
POST https://api.agnt.ai/contacts/bulk-import
| Field | Type | Required | Description |
|---|---|---|---|
contacts | array | Yes | Array of contact objects (max 1,000) |
Each contact in the array:
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Primary email (uniqueness key) |
name | string | No | Full name |
phone | string | No | Phone number |
company | string | No | Company name |
title | string | No | Job title |
timezone | string | No | IANA timezone |
emails | string[] | No | Additional email addresses |
Response:
{
"ok": true,
"total": 50,
"created": 45,
"updated": 3,
"skipped": 0,
"errors": [
{ "index": 12, "email": "bad-email", "error": "Invalid email format" },
{ "index": 37, "email": null, "error": "Email is required" }
]
}Update Contact
PUT https://api.agnt.ai/contacts/:contactId
Accepts the same fields as create. Email addresses provided are merged into the existing emails[] array — they're additive, not a replacement.
Merge Contacts
POST https://api.agnt.ai/contacts/:contactId/merge
| Field | Type | Required | Description |
|---|---|---|---|
mergeContactId | string | Yes | ID of the contact to merge into the target |
The contact at :contactId is the survivor. The contact at mergeContactId is absorbed and deleted. Email arrays are combined. If the source has fields the target doesn't, they carry over.
curl -X POST https://api.agnt.ai/contacts/cnt_abc123/merge \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "mergeContactId": "cnt_def456" }'{
"ok": true,
"contact": {
"id": "cnt_abc123",
"email": "jane@acme.co",
"emails": ["jane@acme.co", "jchen@acme.co", "jane.chen@personal.com"],
"name": "Jane Chen",
"company": "Acme Corp",
"..." : "..."
}
}List Contacts for User
GET https://api.agnt.ai/users/:userId/contacts
| Parameter | Type | Description |
|---|---|---|
search | string | Search by name, email, or company |
page | number | Page number (default: 1) |
perPage | number | Results per page (default: 20) |
Same response shape as the main list endpoint.
Delete Contact
DELETE https://api.agnt.ai/contacts/:contactId
{
"ok": true,
"contact": {
"id": "cnt_abc123",
"message": "Resource deleted successfully"
}
}For Coding Agents
If you're building an agent that needs contact awareness, here's what matters:
- Search is your friend. The
searchquery parameter onGET /contactsmatches across name, email, and company. Use it before creating new contacts to avoid duplicates. - Bulk import is idempotent. If your agent collects contacts from external sources (email parsing, CRM sync, calendar extraction), pipe them through bulk import without worrying about duplicates. The platform handles deduplication by email.
- Check the
consumerfield. If a contact has a non-nullconsumer, that person is a registered user on your platform. Your agent can make delegated API calls on their behalf. - Merge proactively. When your agent detects that two contacts are the same person (same name, overlapping email domains), use the merge endpoint. One clean record is better than two partial ones.
- Timezone matters. Always set
timezonewhen you have it. Scheduling agents need this to compute availability correctly.
For Product Teams
AGNT Contacts is the connective tissue between your users and the people they interact with. A few things to know:
- Contacts are per-user. Each user has their own contact book. There's no shared global directory (though you could build one at the application layer).
- Auto-linking reduces friction. When a contact's email matches a registered user, the link happens automatically. Your team doesn't need to build matching logic.
- Bulk import handles onboarding. When a new user signs up and connects their email or CRM, you can pipe their existing contacts through the bulk import endpoint. The response tells you exactly how many were created, updated, and skipped.
- The merge endpoint is a resolution tool. Duplicate contacts are inevitable. The merge endpoint gives your support team (or your agent) a clean way to resolve them without data loss.
- No contact limits in the current plan. Store as many contacts as your users need. The pagination defaults to 20 per page, but you can request up to 100.