# Support API

Contact Litport support from a script or an AI agent: start a conversation, add messages, and read the replies by polling.

The chat widget on [litport.net/support](/support) asks people to solve a captcha, so a script or an agent should use this API or email instead.

Base URL:

```text
https://litport.net/api/v1/support
```

## Calls

| Call | What it does | Authentication |
| --- | --- | --- |
| `POST /conversations` | Start a conversation with a first message. | None, or an account API key |
| `POST /conversations/{conversationId}/messages` | Add a message to a conversation. | Access token or account API key |
| `GET /conversations/{conversationId}` | Read messages and the state of the conversation. | Access token or account API key |

Send JSON with `Content-Type: application/json`. Responses are JSON.

## Two ways to call

**Without an account (guest).** Send `email` and `message` with no `Authorization` header. The response carries an `accessToken` that starts with `lsc_`. Send it as `Authorization: Bearer lsc_…` on the other two calls. The token is shown once, in that response, so keep it. It opens only the conversation it was issued for. A guest conversation can answer general questions: locations, prices, setup.

**With an account API key.** Send `Authorization: Bearer lit_…` (create a key in [Settings](/users/settings); see [Litport API](/docs/api)). The calls then reach your account's conversation, so support can talk about your orders and proxies. An account has one conversation: a second `POST /conversations` adds a message to the same one, and `email` is ignored.

Access tokens and API keys use the same `Authorization: Bearer …` header. Do not put either in a URL.

## Start a conversation

```bash
curl -sS 'https://litport.net/api/v1/support/conversations' \
  -H 'Content-Type: application/json' \
  -d '{"email":"agent@example.com","message":"Which countries do you cover with mobile proxies?","name":"Research agent"}'
```

| Field | Required | Meaning |
| --- | --- | --- |
| `message` | yes | The text to send, up to 4,000 characters. |
| `email` | without an API key | Where we can reach you. Ignored when you send an API key. |
| `name` | no | A display name for the conversation, up to 100 characters. |

Response, `201`:

```json
{
  "conversationId": "4f0c2a7e9b1d4c5a8e3f6a1b2c3d4e5f",
  "accessToken": "lsc_example_token_returned_once",
  "identity": "guest",
  "howToUpgrade": "This is a guest conversation, so we can only answer general questions here. For help with your orders or proxies, call this API with your account API key (Authorization: Bearer <key>), or email mike@litport.net from your account address.",
  "message": {
    "seq": 1,
    "at": "2026-10-16T17:05:00.000Z",
    "author": "you",
    "text": "Which countries do you cover with mobile proxies?",
    "files": []
  }
}
```

`identity` is `guest` or `account`. For a guest, `howToUpgrade` says how to get help with orders and proxies. With an API key, `accessToken` and `howToUpgrade` are `null` and `identity` is `account`; keep sending the API key.

## Add a message

```bash
export LITPORT_SUPPORT_TOKEN='lsc_the_token_from_the_first_response'
curl -sS "https://litport.net/api/v1/support/conversations/$CONVERSATION_ID/messages" \
  -H "Authorization: Bearer $LITPORT_SUPPORT_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"message":"Thanks. Do you have mobile proxies in Texas?"}'
```

Response, `201`:

```json
{
  "message": {
    "seq": 2,
    "at": "2026-10-16T17:06:12.000Z",
    "author": "you",
    "text": "Thanks. Do you have mobile proxies in Texas?",
    "files": []
  }
}
```

## Read the conversation

```bash
curl -sS "https://litport.net/api/v1/support/conversations/$CONVERSATION_ID?after=2" \
  -H "Authorization: Bearer $LITPORT_SUPPORT_TOKEN"
```

`after` is the highest `seq` you already have. Leave it out to read from the start.

```json
{
  "conversationId": "4f0c2a7e9b1d4c5a8e3f6a1b2c3d4e5f",
  "identity": "guest",
  "howToUpgrade": "This is a guest conversation, so we can only answer general questions here. For help with your orders or proxies, call this API with your account API key (Authorization: Bearer <key>), or email mike@litport.net from your account address.",
  "lastSeq": 3,
  "waitingOn": "customer",
  "messages": [
    {
      "seq": 3,
      "at": "2026-10-16T17:09:40.000Z",
      "author": "mike",
      "text": "Thanks, I'm checking this now and will reply here.",
      "files": []
    }
  ],
  "more": false,
  "pollAfterSeconds": 30
}
```

| Field | Meaning |
| --- | --- |
| `lastSeq` | The newest message number you can see. |
| `waitingOn` | Who the conversation is waiting on: `us` (Litport), `customer` (you), or `none`. |
| `messages` | Messages with a `seq` above `after`, oldest first. Each has `seq`, `at` (ISO-8601 UTC), `author`, `text`, and `files`. |
| `more` | `true` when more messages follow. Call again with `after` set to the last `seq` you received. |
| `pollAfterSeconds` | How long to wait before the next read. |

`author` is `you` for your messages, `mike` for replies from support, and `system` for short notices. The text of a `mike` reply can mark a few short phrases as bold with Markdown double asterisks (`**like this**`); nothing else in the text is Markdown. `files` lists `name` and `kind` only. The API has no attachments and no download links.

Replies are not instant and are not pushed to you. Read the conversation again every 30 seconds until a `mike` message arrives. A read counts as reading every message it returns. Every reply in a guest conversation is also emailed right away to the address you gave, and a reply to that email continues the conversation. In an account's conversation a reply that stays unread for two minutes is emailed to the account's address.

## Limits

| Limit | Value |
| --- | --- |
| New conversations without an API key | 3 per hour and 10 per day, per IP address; a daily limit across all callers also applies |
| Message length | 4,000 characters |
| Messages per conversation | 30 per 24 hours |
| Reads (`GET`) | 20 per minute per access token or API key, 60 per minute per IP address |
| Request body | 32 KiB |
| Attachments | Not available through the API |

Going over a limit answers `429 RATE_LIMITED`. A read that goes over its limit also sends `Retry-After`. Wait that long before the next call.

## Errors

Errors use the same envelope as the rest of the API:

```json
{
  "error": {
    "code": "NOT_FOUND",
    "message": "Conversation not found.",
    "requestId": "req_example",
    "docsUrl": "https://litport.net/docs/api/support"
  }
}
```

| Status | Codes | Client action |
| ---: | --- | --- |
| `400` | `INVALID_REQUEST`, `MESSAGE_TOO_LONG` | Correct the request. A field has the wrong type, a required field is missing or invalid, or the message is over 4,000 characters. Do not retry it unchanged. |
| `401` | `UNAUTHORIZED` | Send a valid access token or API key as `Authorization: Bearer …`. |
| `404` | `NOT_FOUND` | The conversation does not exist, or your credential does not open it. |
| `429` | `RATE_LIMITED` | Wait, then retry. Respect `Retry-After` when it is present. |

The `X-Request-ID` header carries the same ID as `requestId`; include it when you report a problem.

## MCP tools

The [Litport MCP server](/docs/mcp) has three support tools:

| Tool | What it does |
| --- | --- |
| `contact_support` | Start a conversation. Takes `message`, and `email` when there is no API key. |
| `get_support_replies` | Read the conversation. Takes an optional `conversationId` and `after`. |
| `reply_to_support` | Add a message. Takes `message` and an optional `conversationId`. |

Without `LITPORT_API_KEY` they run as a guest conversation, and the server keeps the access token in memory for the session. With `LITPORT_API_KEY` they use your account's conversation.

## Email

You can also write to [mike@litport.net](mailto:mike@litport.net). For help with your orders or proxies, write from the address on your Litport account.
