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.

---

# vCards
description: Bulk-import contacts from vCard streams and export single contacts as .vcf files

---


# vCards

Round-trip contacts through the RFC 6350 vCard format. Use these endpoints to migrate contacts from Apple Contacts, Google Contacts, LinkedIn exports, or other vCard-producing address books.

---

## Import vCards `POST`


Bulk-import contacts from a vCard body. The request body must be `text/vcard` or `text/x-vcard`, UTF-8 encoded, and at most 5 MB containing up to 1000 cards.

Each card is imported in isolation, so one bad card doesn't poison the rest. The response is always `200 OK` — partial failure is reflected in the `created_count` / `error_count` and per-card `results` list.

### Request headers

| Header | Required | Description |
| :--- | :--- | :--- |
| `Content-Type` | Yes | `text/vcard` or `text/x-vcard` |
| `X-API-Key` | Yes | Your API key |

### Response (200)

```json
{
    "created_count": 2,
    "error_count": 1,
    "results": [
      { "index": 0, "status": "created", "contact": { /* Contact object */ } },
      { "index": 1, "status": "created", "contact": { /* Contact object */ } },
      { "index": 2, "status": "error", "error": "vCard missing required FN field" }
    ]
}
```

| Field | Type | Description |
| :--- | :--- | :--- |
| `created_count` | integer | Number of contacts created |
| `error_count` | integer | Number of cards that failed to import |
| `results[].index` | integer | 0-based position within the uploaded stream |
| `results[].status` | string | `"created"` or `"error"` |
| `results[].contact` | object | Full [Contact object](/docs/api/contacts/manage#contact-object) (when `status == "created"`) |
| `results[].error` | string | Rejection reason (when `status == "error"`) |

### Error responses

| Status | Description |
| :--- | :--- |
| 400 | Body is not UTF-8 |
| 413 | Body exceeds 5 MB or 1000 cards |
| 415 | Content-Type is not `text/vcard` or `text/x-vcard` |
| 422 | Body contains no complete `BEGIN:VCARD` / `END:VCARD` pairs |

### Code examples

**cURL**

```bash
curl -X POST "https://inkbox.ai/api/v1/contacts/import" \\
    -H "X-API-Key: YOUR_API_KEY" \\
    -H "Content-Type: text/vcard" \\
    --data-binary @contacts.vcf
```

**JavaScript**

```javascript
import { readFile } from "node:fs/promises";

const vcfBody = await readFile("contacts.vcf", "utf-8");
const response = await fetch("https://inkbox.ai/api/v1/contacts/import", {
    method: "POST",
    headers: {
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "text/vcard",
    },
    body: vcfBody,
});
const result = await response.json();
console.log(result.created_count, result.error_count);
```

**Python**

```python
import requests

with open("contacts.vcf", "rb") as fh:
    response = requests.post(
        "https://inkbox.ai/api/v1/contacts/import",
        headers={
            "X-API-Key": "YOUR_API_KEY",
            "Content-Type": "text/vcard",
        },
        data=fh.read(),
    )
result = response.json()
print(result["created_count"], result["error_count"])
```

---

## Export vCard `GET`


Download a single contact as a `text/vcard; charset=utf-8` file. The response includes a `Content-Disposition: attachment` header with a filename derived from the contact's `preferred_name`.

### Path parameters

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

### Response (200)

Response body is raw vCard text:

```
BEGIN:VCARD
VERSION:3.0
FN:Jane Doe
N:Doe;Jane;;;
EMAIL;TYPE=WORK:jane@acme.example
TEL:+15551234567
END:VCARD
```

### Code examples

**cURL**

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

**JavaScript**

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

**Python**

```python
import requests

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