# The Postal Company API — Agent Skill

Use this skill to send physical letters anywhere in the world via The Postal Company API.

## Setup

You need an API key. The user should provide it or store it in an environment variable (e.g. `TPC_API_KEY`). API keys start with `tpc_`.

**Base URL:** `https://thepostalcompany.com`

**Authentication:** Pass the API key as a Bearer token in the `Authorization` header:
```
Authorization: Bearer tpc_...
```

## Endpoints

### Create a letter

```
POST /api/v1/letters
```

**Request body (JSON):**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `recipient` | string | No | Recipient name (max 30 chars) |
| `address` | object | Yes | Postal address (see below) |
| `content` | string | Yes | Letter body text. Use `\n` for line breaks. |
| `send` | boolean | No | `true` (default) sends immediately. `false` creates a draft. |

**Address object:**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `street` | string | Yes | Street name |
| `number` | string | Yes | House/building number |
| `suffix` | string | No | Address addition (e.g. "2nd floor") |
| `postalcode` | string | Yes | Postal/ZIP code |
| `city` | string | Yes | City |
| `country` | string | Yes | ISO 3166-1 alpha-2 code (e.g. "NL", "US", "DE") |

**Response (201):**
```json
{
  "id": "uuid",
  "status": "processing",
  "balance_cents": 750
}
```

When `send: false`, the response omits `balance_cents` and status is `"draft"`.

### List letters

```
GET /api/v1/letters
```

**Response (200):**
```json
{
  "letters": [
    {
      "id": "uuid",
      "status": "sent",
      "recipient": "Jane Doe",
      "address": { ... },
      "content": "...",
      "created_at": "2026-04-14T10:00:00.000Z",
      "updated_at": "2026-04-14T10:00:05.000Z"
    }
  ]
}
```

### Get a letter

```
GET /api/v1/letters/{letterId}
```

Returns a single letter object. Returns 404 if not found or not owned by your account.

### Update a draft

```
PATCH /api/v1/letters/{letterId}
```

Only works on letters with `"draft"` status. All fields are optional — only include what you want to change.

**Request body (JSON):**

| Field | Type | Description |
|-------|------|-------------|
| `recipient` | string | New recipient name |
| `address` | object | New address (full object required if updating) |
| `content` | string | New letter content |

Returns the full updated letter object. Returns 409 if the letter is not a draft.

### Send a draft

```
POST /api/v1/letters/{letterId}/send
```

Sends a draft letter. Deducts balance and queues for printing/delivery. No request body needed.

**Response (200):**
```json
{
  "id": "uuid",
  "status": "processing",
  "balance_cents": 750
}
```

Returns 402 if insufficient balance, 409 if not a draft.

## Error handling

| Status | Meaning |
|--------|---------|
| 400 | Invalid request (missing fields, bad address) |
| 401 | Invalid or missing API key |
| 402 | Insufficient balance (each letter costs €2.25) |
| 404 | Letter not found or not owned by your account |
| 409 | Letter is not in the required status for this operation |
| 500 | Server error |

All errors return `{ "error": "description" }`.

## Typical workflows

### Send a letter immediately

```bash
curl -X POST https://thepostalcompany.com/api/v1/letters \
  -H "Authorization: Bearer $TPC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient": "Jane Doe",
    "address": {
      "street": "Keizersgracht",
      "number": "123",
      "postalcode": "1015 CJ",
      "city": "Amsterdam",
      "country": "NL"
    },
    "content": "Dear Jane,\n\nYour letter content here.\n\nBest regards"
  }'
```

### Draft, review, then send

```bash
# 1. Create a draft
curl -X POST https://thepostalcompany.com/api/v1/letters \
  -H "Authorization: Bearer $TPC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient": "Jane Doe",
    "address": {
      "street": "Keizersgracht",
      "number": "123",
      "postalcode": "1015 CJ",
      "city": "Amsterdam",
      "country": "NL"
    },
    "content": "Dear Jane,\n\nDraft content.\n\nBest regards",
    "send": false
  }'

# 2. Update the draft (optional)
curl -X PATCH https://thepostalcompany.com/api/v1/letters/{id} \
  -H "Authorization: Bearer $TPC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "content": "Dear Jane,\n\nRevised content.\n\nBest regards" }'

# 3. Send it
curl -X POST https://thepostalcompany.com/api/v1/letters/{id}/send \
  -H "Authorization: Bearer $TPC_API_KEY"
```

## Letter statuses

| Status | Meaning |
|--------|---------|
| `draft` | Saved but not yet sent. Can be updated or sent. |
| `processing` | Payment received, letter is being printed. |
| `sent` | Letter has been handed off to postal service. |
| `delivered` | Letter confirmed delivered. |
| `failed` | Something went wrong during processing. |

## Important notes

- Each letter costs **€2.25** via API. Top up your balance at https://thepostalcompany.com/balance
- Letter content supports Latin, Korean, Chinese, and Arabic scripts
- Line breaks in content (`\n`) are preserved in the printed letter
- The `country` field must be a valid ISO 3166-1 alpha-2 code
- Letters are printed on A4 paper with The Postal Company branding
- You can only access letters belonging to your own account
