> ## Documentation Index
> Fetch the complete documentation index at: https://docs.staging.relayapp.im/llms.txt
> Use this file to discover all available pages before exploring further.

# Voice memos

> Send an uploaded audio Attachment as a voice memo.

Upload the audio first, as any [Attachment](https://docs.staging.relayapp.im/messages/attachments.md), giving `duration_ms` in the allocation so the app can show the length. Then call `POST /v1/chats/{chatId}/voicememo` ([reference](https://docs.staging.relayapp.im/api-reference/messages/send-a-voice-memo-to-a-chat.md)) with the completed `attachment_id`. The SDK method is `relay.chats.sendVoicememo`.

Relay refuses anything that is not `audio/*` on this route. Instead of an upload, `voice_memo_url` accepts a public HTTPS audio URL up to 10 MiB (10,485,760 bytes), checked the same way as [other URL media](https://docs.staging.relayapp.im/messages/import-media.md#apply-the-url-safety-checks). Send one of the two fields, not both.

## Send the voice memo

Send the body to the voice memo route:

**Preview**

A voice memo; tap play

**JSON**

```json theme={null}
{
  "attachment_id": "01993d50-d263-7d6b-87ce-90aba89b7815"
}
```

```bash cURL theme={null}
curl -sS -X POST "https://api.staging.relayapp.im/v1/chats/$CHAT_ID/voicememo" \
  -H "Authorization: Bearer $RELAY_AGENT_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"attachment_id":"01993d50-d263-7d6b-87ce-90aba89b7815"}'
```

```bash cURL from a URL theme={null}
curl -sS -X POST "https://api.staging.relayapp.im/v1/chats/$CHAT_ID/voicememo" \
  -H "Authorization: Bearer $RELAY_AGENT_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"voice_memo_url":"https://example.com/hello.m4a"}'
```

```typescript TypeScript SDK theme={null}
const { voice_memo } = await relay.chats.sendVoicememo(chatId, {
  attachment_id: "01993d50-d263-7d6b-87ce-90aba89b7815",
});
```

## What you get back

Relay returns `202` with a `voice_memo` object: the message ID, its delivery status, the chat, and the Attachment with a download URL and the file's metadata. The person hears it as a voice memo on their phone rather than as a file.

```json theme={null}
{
  "voice_memo": {
    "id": "01993d50-e1a2-7c3b-9d4e-5f6a7b8c9d0e",
    "from": "atlas",
    "to": ["alice"],
    "status": "sent",
    "voice_memo": {
      "id": "01993d50-d263-7d6b-87ce-90aba89b7815",
      "url": "<download URL>",
      "filename": "hello.m4a",
      "mime_type": "audio/mp4",
      "size_bytes": 48213,
      "duration_ms": 4200
    },
    "created_at": "2026-10-01T15:04:05.000Z",
    "chat": {
      "id": "01993d4f-8a7b-7c6d-9e8f-0a1b2c3d4e5f",
      "handles": [],
      "is_group": false
    }
  }
}
```

## When it fails

| Status | Code | Cause | Next action |
| - | - | - | - |
| `400` | [1005](https://docs.staging.relayapp.im/api-reference/errors.md#1005) | Both fields or neither were sent. | Send one. |
| `404` | [2001](https://docs.staging.relayapp.im/api-reference/errors.md#2001) | No chat has that ID, or the Attachment is unknown. | Check both IDs. |
| `413` | [2006](https://docs.staging.relayapp.im/api-reference/errors.md#2006) | The audio at `voice_memo_url` is over 10 MiB. | Upload it as an Attachment. |
| `422` | [2006](https://docs.staging.relayapp.im/api-reference/errors.md#2006) | The Attachment is not complete or not audio, or the URL failed a check. | Confirm the upload, or fix the URL. |

## Next steps

* [Upload attachments](https://docs.staging.relayapp.im/messages/attachments.md)
* [Import media from a URL](https://docs.staging.relayapp.im/messages/import-media.md)
* [Build message parts](https://docs.staging.relayapp.im/messages/parts.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.