> For the complete documentation index, see [llms.txt](https://docs.bird.com/api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bird.com/api/conversations-api/api-reference/conversations-messaging/create-pre-signed-upload.md).

# Create pre-signed upload

This API generates a pre-signed URL for media uploads. It responds with information required to build a subsequent form data request to upload the media to an S3 bucket. Please refer to [Examples](#examples) below on how to use it.

## Create a presigned media upload

> Creates a pre-signed URL to upload media that can be used when sending messages in a conversation. The maximum fize size is 100MiB.<br>

```json
{"openapi":"3.0.3","info":{"title":"Conversations","version":"v1"},"tags":[{"name":"conversation","description":"Conversations are a collection of messages between two or more participants."}],"servers":[{"url":"https://api.bird.com","description":"Production API"}],"security":[{"accessKey":[]}],"components":{"securitySchemes":{"accessKey":{"description":"Uses the Authorization header: 'AccessKey ' followed by your access key token","scheme":"AccessKey","type":"http"}},"schemas":{"CreatePresignedUpload":{"type":"object","additionalProperties":false,"required":["contentType"],"properties":{"contentType":{"type":"string","description":"The MIME type of the media being uploaded.","minLength":1}}},"PresignedUpload":{"type":"object","additionalProperties":false,"required":["mediaUrl","uploadUrl","uploadMethod","uploadFormData"],"properties":{"mediaUrl":{"type":"string","description":"The URL to use when sending messages with this media. Must be passed in the `attachments` object.","format":"uri"},"uploadUrl":{"type":"string","description":"The URL to upload the media using form data encoding. The media must be sent with the field name `file` in addition to fields in `uploadFormData`.\n","format":"uri"},"uploadMethod":{"type":"string","description":"The method to use when uploading the media, will always be POST."},"uploadFormData":{"type":"object","description":"Form data fields that must be passed in addition to the field `file` when uploading the media to `uploadUrl`.\n"}}},"error.detailed":{"additionalProperties":false,"description":"An error returned from the API that includes additional details about the error. The `details` property can contain any additional information about the error that may be helpful for debugging or understanding the error.\n","properties":{"code":{"description":"A unique code that identifies the error. This code can be used to programmatically identify the error.","minLength":3,"type":"string"},"details":{"additionalProperties":true,"description":"Any additional information about the error that may be helpful for debugging or understanding the error.","type":"object"},"message":{"description":"A human-readable message that describes the error.","minLength":1,"type":"string"}},"required":["code","message"],"title":"DetailedError","type":"object"},"error.validation":{"additionalProperties":false,"description":"A validation error returned from the API. The `details` map keys are JSON paths\npointing into the request body / parameters; values are arrays of human-readable\nmessages describing each problem with that path.\n","properties":{"code":{"description":"A unique code that identifies the error. This code can be used to programmatically identify the error.","minLength":3,"type":"string"},"details":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"description":"Per-field validation messages keyed by JSON path.","type":"object"},"message":{"description":"A human-readable message that describes the error.","minLength":1,"type":"string"}},"required":["code","message"],"title":"ValidationError","type":"object"}},"responses":{"notFound":{"$ref":"#/components/responses/error.response.not_found"},"error.response.not_found":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.detailed"}}},"description":"The requested resource was not found."},"validationFailed":{"$ref":"#/components/responses/error.response.invalid_request"},"error.response.invalid_request":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.validation"}}},"description":"The request contains invalid parameters or body fields."}}},"paths":{"/workspaces/{workspaceId}/conversations/{conversationId}/presigned-upload":{"post":{"summary":"Create a presigned media upload","operationId":"createPresignedMediaUpload","description":"Creates a pre-signed URL to upload media that can be used when sending messages in a conversation. The maximum fize size is 100MiB.\n","tags":["conversation"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePresignedUpload"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignedUpload"}}}},"404":{"$ref":"#/components/responses/notFound"},"422":{"$ref":"#/components/responses/validationFailed"}}}}}}
```

## Examples

In the following example, we'll generate a pre-signed upload URL, then use it to upload media, and finally send a message with it:

1. Generate URL

{% tabs %}
{% tab title="Request" %}

```bash
curl -X POST "https://api.bird.com/workspaces/a1405560-c8d3-4b1a-877d-3f449ad95352/conversations/02ec2ac2-ebec-42d3-a5f4-e6f3a9edf418/presigned-upload" \
-H "Authorization: AccessKey abcd"
```

{% endtab %}

{% tab title="Response (200 - OK)" %}

```json
{
  "mediaUrl": "https://media.api.bird.com/workspaces/a1405560-c8d3-4b1a-877d-3f449ad95352/conversations/02ec2ac2-ebec-42d3-a5f4-e6f3a9edf418/media/e867a2ac-2df5-40be-a5d4-e452d7156048",
  "uploadUrl": "https://channels--message-media--151603429280--euw1.s3.eu-west-1.amazonaws.com",
  "uploadMethod": "POST",
  "uploadFormData": {
    "Content-Type": "image/png",
    "acl": "private",
    "bucket": "channels--message-media--151603429280--euw1",
    "key": "a1405560-c8d3-4b1a-877d-3f449ad95352/e867a2ac-2df5-40be-a5d4-e452d7156048",
    "policy": "c29tZSByYW5kb20gYmFzZTY0IHNvbWUgcmFuZG9tIGJhc2U2NCBzb21lIHJhbmRvbSBiYXNlNjQ=",
    "x-amz-algorithm": "AWS4-HMAC-SHA256",
    "x-amz-credential": "ASIAZIY3TY7LKB5VSROM/20241202/us-west-1/s3/aws4_request",
    "x-amz-date": "20241202T151755Z",
    "x-amz-meta-allowed-paths": "/workspaces/a1405560-c8d3-4b1a-877d-3f449ad95352/conversations/02ec2ac2-ebec-42d3-a5f4-e6f3a9edf418/media/e867a2ac-2df5-40be-a5d4-e452d7156048",
    "x-amz-meta-channel-id": "cb4b1ebc-34e6-5a7a-a375-f6f2f131d88f",
    "x-amz-meta-conversation-id": "02ec2ac2-ebec-42d3-a5f4-e6f3a9edf418",
    "x-amz-security-token": "dmJ0h6xCpr/DysEQmSWORwF7HggMJq6GSSAXUCA0lDY=",
    "x-amz-signature": "22986b67e42558bc2f44b970d8a8c0357832540245a5c80df1229f4166c9d73c"
  }
}
```

{% endtab %}
{% endtabs %}

2. Upload media to pre-signed URL

All of the fields in `uploadFormData` from the previous response need to be passed as form data string fields. Additionally, the field `file` must contain the media file you'd like to upload.

The response status is 204 (No Content).

{% tabs %}
{% tab title="Request" %}

```bash
curl 'https://channels--message-media--151603429280--euw1.s3.eu-west-1.amazonaws.com' \
-F 'Content-Type="image/png"' \
-F 'acl="private"' \
-F 'bucket="channels--message-media--151603429280--euw1"' \
-F 'key="a1405560-c8d3-4b1a-877d-3f449ad95352/e867a2ac-2df5-40be-a5d4-e452d7156048"' \
-F 'policy="c29tZSByYW5kb20gYmFzZTY0IHNvbWUgcmFuZG9tIGJhc2U2NCBzb21lIHJhbmRvbSBiYXNlNjQ="' \
-F 'x-amz-algorithm="AWS4-HMAC-SHA256"' \
-F 'x-amz-credential="ASIAZIY3TY7LKB5VSROM/20241202/us-east-2/s3/aws4_request"' \
-F 'x-amz-date="20241202T151755Z"' \
-F 'x-amz-meta-allowed-paths="/workspaces/a1405560-c8d3-4b1a-877d-3f449ad95352/conversations/02ec2ac2-ebec-42d3-a5f4-e6f3a9edf418/media/e867a2ac-2df5-40be-a5d4-e452d7156048"' \
-F 'x-amz-meta-channel-id="cb4b1ebc-34e6-5a7a-a375-f6f2f131d88f"' \
-F 'x-amz-meta-conversation-id="02ec2ac2-ebec-42d3-a5f4-e6f3a9edf418"' \
-F 'x-amz-security-token="dmJ0h6xCpr/DysEQmSWORwF7HggMJq6GSSAXUCA0lDY="' \
-F 'x-amz-signature="22986b67e42558bc2f44b970d8a8c0357832540245a5c80df1229f4166c9d73c"' \
-F 'file=@"./bird.png"'
```

{% endtab %}
{% endtabs %}

3. Send message with media

{% tabs %}
{% tab title="Request" %}

```bash
curl -X POST "https://api.bird.com/workspaces/a1405560-c8d3-4b1a-877d-3f449ad95352/conversations/02ec2ac2-ebec-42d3-a5f4-e6f3a9edf418/messages" \
-H "Content-Type: application/json" \
-H "Authorization: AccessKey abcd" \
-d '{
  "participantType": "accessKey",
  "participantId": "0c0defe3-c98d-46d9-a9bf-febc1e08aa0c",
  "addMissingParticipants": true,
  "recipients": [
    {
      "type": "to",
      "identifierKey": "emailaddress",
      "identifierValue": "some.customer@example.com"
    }
  ],
  "body": {
    "type": "html",
    "html": {
      "attachments": [
        {
          "inline": true,
          "filename": "my_file",
          "mediaUrl": "https://media.api.bird.com/workspaces/a1405560-c8d3-4b1a-877d-3f449ad95352/conversations/02ec2ac2-ebec-42d3-a5f4-e6f3a9edf418/media/e867a2ac-2df5-40be-a5d4-e452d7156048"
        }
      ],
      "html": "<!doctype html><body><img src=\"cid:my_file\"></img></body></html>"
    }
  }
}'
```

{% endtab %}

{% tab title="Response (201 - Created)" %}

```json
{
  "id": "fec68d3d-bd43-4e73-8ef9-15d7b078b20e",
  "conversationId": "02ec2ac2-ebec-42d3-a5f4-e6f3a9edf418",
  "reference": "",
  "sender": {
    "id": "68b80b8d-8060-42df-bda3-73505a8fdb84",
    "type": "accessKey",
    "status": "active",
    "displayName": "My first email key",
    "avatarUrl": ""
  },
  "draft": false,
  "recipients": [
    {
      "type": "to",
      "id": "8f0b5377-2edc-4116-a8e8-6a475f245a04",
      "identifierKey": "emailaddress",
      "identifierValue": "some.customer@example.com",
      "platformAddress": "some.customer@example.com",
      "contactAnnotation": {
        "name": "John Doe"
      }
    }
  ],
  "status": "accepted",
  "source": "conversations",
  "body": {
    "type": "html",
    "html": {
      "html": "<!doctype html><body><img src=\"cid:my_file\"></img></body></html>",
      "attachments": [
        {
          "mediaUrl": "https://media.api.bird.com/workspaces/a1405560-c8d3-4b1a-877d-3f449ad95352/conversations/02ec2ac2-ebec-42d3-a5f4-e6f3a9edf418/media/e867a2ac-2df5-40be-a5d4-e452d7156048",
          "filename": "my_file",
          "inline": true
        }
      ]
    }
  },
  "interactions": null,
  "createdAt": "2024-12-02T17:17:24.419Z",
  "updatedAt": "2024-12-02T17:17:24.419Z"
}
```

{% endtab %}
{% endtabs %}
