Inkbox

> # Documentation index
> Fetch the complete documentation index at: https://inkbox.ai/sitemap.xml
> Use this file to discover all available pages before exploring further.

---

# Contact Access Control
description: Grant and revoke agent identity access to contacts — wildcard default with per-identity overrides

---


# Contact Access Control

Control which [agent identities](/docs/api/identities) can see a given contact. Contacts use a **wildcard-default** model: a newly created contact has one access row with `identity_id: null`, which grants visibility to every active agent in the organization. Narrow that set by revoking identities (the wildcard is materialized into per-identity rows the first time you revoke); widen it by resetting to the wildcard.

> Granting a per-identity rule on a wildcard contact returns `409 redundant_grant`. The wildcard already grants everyone; revoke it first if you want a narrower set.

Humans (Clerk JWT) and admin API keys always see every contact regardless of access rules. Only agent-scoped API keys are narrowed by the rules below.

---

## Grant identity access `POST`


Grant an identity access to a contact, or reset the contact to the wildcard.

> **Auth:** admin API key or Clerk JWT only. Agent-scoped API keys cannot widen access.

### Path parameters

| Parameter | Type | Description |
| :--- | :--- | :--- |
| `contact_id` | UUID | Contact ID |

### Request body

| Field | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| `identity_id` | UUID \| null | Yes | Identity to grant, or `null` to reset to the wildcard (drops every explicit row and inserts a single wildcard row — this **widens** visibility) |

### Request example

```json
{
    "identity_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
}
```

### Response (201)

```json
{
    "id": "r1a2b3c4-d5e6-7890-abcd-ef1234567890",
    "contact_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "identity_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "created_at": "2026-04-21T12:30:00Z"
}
```

### Error responses

| Status | Description |
| :--- | :--- |
| 404 | Contact or identity not found in your organization |
| 409 | Identity already has a per-identity grant; or `redundant_grant` — the wildcard already grants this identity |

### Code examples

**cURL**

```bash
curl -X POST "https://inkbox.ai/api/v1/contacts/CONTACT_ID/access" \\
    -H "X-API-Key: YOUR_API_KEY" \\
    -H "Content-Type: application/json" \\
    -d '{"identity_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901"}'
```

**JavaScript**

```javascript
const response = await fetch(
    `https://inkbox.ai/api/v1/contacts/${contactId}/access`,
    {
        method: "POST",
        headers: {
            "X-API-Key": "YOUR_API_KEY",
            "Content-Type": "application/json",
        },
        body: JSON.stringify({
            identity_id: "b2c3d4e5-f6a7-8901-bcde-f12345678901",
        }),
    }
);
const rule = await response.json();
```

**Python**

```python
import requests

response = requests.post(
    f"https://inkbox.ai/api/v1/contacts/{contact_id}/access",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"identity_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901"},
)
rule = response.json()
```

---

## List access rules `GET`


List the access rows for a contact. The response is either a single wildcard row (`identity_id: null`, the default state) or a list of explicit per-identity rows — never a mixed state. Consumer UIs typically render the wildcard case as "All agents".

### Path parameters

| Parameter | Type | Description |
| :--- | :--- | :--- |
| `contact_id` | UUID | Contact ID |

### Response (200)

```json
[
    {
      "id": "r1a2b3c4-d5e6-7890-abcd-ef1234567890",
      "contact_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "identity_id": null,
      "created_at": "2026-04-21T12:30:00Z"
    }
]
```

### Code examples

**cURL**

```bash
curl -X GET "https://inkbox.ai/api/v1/contacts/CONTACT_ID/access" \\
    -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const response = await fetch(
    `https://inkbox.ai/api/v1/contacts/${contactId}/access`,
    { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const rules = await response.json();
```

**Python**

```python
import requests

response = requests.get(
    f"https://inkbox.ai/api/v1/contacts/{contact_id}/access",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
rules = response.json()
```

---

## Revoke identity access `DELETE`


Revoke an identity's access. If the contact is currently wildcard-access, the server atomically fans out the wildcard into per-identity rows for every active agent in the org and then drops the target identity's row — so the revoke narrows without also revoking everyone else.

A claimed agent API key may only revoke itself. Admins and JWT users may revoke any identity.

### Path parameters

| Parameter | Type | Description |
| :--- | :--- | :--- |
| `contact_id` | UUID | Contact ID |
| `identity_id` | UUID | Identity to revoke |

### Response

Returns `204 No Content` on success.

### Error responses

| Status | Description |
| :--- | :--- |
| 403 | Claimed agent attempted to revoke another identity |
| 404 | Contact or access row not found (including the duplicate-revoke race case) |

### Code examples

**cURL**

```bash
curl -X DELETE "https://inkbox.ai/api/v1/contacts/CONTACT_ID/access/IDENTITY_ID" \\
    -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
await fetch(
    `https://inkbox.ai/api/v1/contacts/${contactId}/access/${identityId}`,
    {
        method: "DELETE",
        headers: { "X-API-Key": "YOUR_API_KEY" },
    }
);
```

**Python**

```python
import requests

requests.delete(
    f"https://inkbox.ai/api/v1/contacts/{contact_id}/access/{identity_id}",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
```

---

## Access rule object

| Field | Type | Description |
| :--- | :--- | :--- |
| `id` | UUID | Unique access rule identifier |
| `contact_id` | UUID | The contact this rule grants access to |
| `identity_id` | UUID \| null | The [agent identity](/docs/api/identities) granted access, or `null` for the wildcard sentinel ("every active agent sees this contact") |
| `created_at` | string | Creation timestamp (ISO 8601) |
