# Support (Contact us) — Mobile Integration Guide

Settings → Contact us. The user picks a topic, writes a message, and can add up to 3 photos. One endpoint.

## What's new

- **2026-10-29** — First version. `POST /api/support/tickets` is new. Build the Contact us screen on it.

---

## 1. Topics

The topics are **not** served by the API. Hardcode the four slugs and their labels in the app. The API rejects any other slug with 400.

| `topic`        | Label in the app          | Description line                                     |
| -------------- | ------------------------- | ---------------------------------------------------- |
| `BUG`          | Something isn't working   | For app bugs, broken features or unexpected behaviour |
| `ACCOUNT_HELP` | Account or login help     | For account access, verification or account information issue |
| `FEEDBACK`     | Feedback or suggestion    | Share an idea or tell us how Clustr could be better  |
| `OTHER`        | Something else            | For anything that doesn't fit the above options      |

Labels are yours. The server never sends display text.

## 2. Send a ticket

`POST /api/support/tickets` — needs the usual `Authorization` header.

```json
{
  "topic": "BUG",
  "message": "The feed does not load after I log in.",
  "attachments": [
    { "type": "image", "url": "<publicUrl from presign>", "width": 1170, "height": 2532, "size": 245000 }
  ],
  "appVersion": "1.4.0",
  "platform": "IOS",
  "osVersion": "18.1"
}
```

| Field         | Rule                                                          |
| ------------- | ------------------------------------------------------------- |
| `topic`       | Required. One of the four slugs.                              |
| `message`     | Required. 10–2000 characters after trim.                      |
| `attachments` | Optional. Max 3. Images only. Same item shape as a post's `media`. |
| `appVersion`  | Optional. Up to 40 characters. Send it for `BUG`.             |
| `platform`    | Optional. `IOS` or `ANDROID`.                                 |
| `osVersion`   | Optional. Up to 40 characters.                                |

Response `201`:

```json
{ "success": true, "data": { "id": "…", "createdAt": "2026-10-29T10:00:00.000Z" } }
```

## 3. Photos

1. Upload each photo with `POST /api/media/presign`, then PUT to the signed URL. See the [media upload guide](../media-upload/mobile-media-upload-guide.md).
2. Put the resulting `publicUrl` in `attachments[].url`.
3. Do **not** call `/api/media/attach`. The ticket request attaches them.

## 4. Errors

| Status | Code / meaning                                   | What to do                                              |
| ------ | ------------------------------------------------ | ------------------------------------------------------- |
| 400    | Bad topic, short or long message, more than 3 photos | Fix the form. Validate the same limits in the app first. |
| 415    | A file is not a real image                       | Ask for a different photo.                              |
| 422    | `MEDIA_BLOCKED`                                  | A photo failed the check. Ask for a different one.      |
| 503    | `MEDIA_CHECK_UNAVAILABLE`                        | Not the user's fault. Let them retry.                   |
| 429    | Rate limit: 5 tickets per hour                   | Show "Try again later".                                 |

## 5. After sending

Show a "Thanks, we got your message" screen. There is no ticket list and no reply in the app. Support answers by email, to the address on the user's account.
