---
updatedAt: 2026-08-24T09:14:57.000Z
agentTools:
  projectIndex: https://developers.vibe.co/llms.txt
---

# Get presigned upload URL for a video asset

Returns a presigned S3 POST target. Upload the video by issuing a multipart POST to `upload_url` with every entry of `fields` and a `file` field containing the file. Then pass the returned `upload_id` to `POST /creatives/video` to register the creative.
**Scopes:**
`creatives:write`
<br>*Rate limits*:<br>Burst: `5/s`<br>Steady: `60/m`


# OpenAPI definition

```json
{
  "openapi": "3.1.0",
  "paths": {
    "/creatives/upload-url": {
      "get": {
        "description": "Returns a presigned S3 POST target. Upload the video by issuing a multipart POST to `upload_url` with every entry of `fields` and a `file` field containing the file. Then pass the returned `upload_id` to `POST /creatives/video` to register the creative.\n**Scopes:**\n`creatives:write`\n<br>*Rate limits*:<br>Burst: `5/s`<br>Steady: `60/m`\n",
        "operationId": "getCreativeUploadUrl",
        "parameters": [
          {
            "name": "advertiser_id",
            "required": true,
            "in": "query",
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "name": "account_id",
            "required": false,
            "in": "query",
            "description": "Required only for embedded apps.",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Presigned URL",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreativeUploadUrl"
                }
              }
            }
          },
          "400": {
            "description": "Bad request error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "missingApiKey": {
                    "summary": "Missing API key",
                    "value": {
                      "error": {
                        "type": "validation",
                        "message": "Missing API Key",
                        "status": 400,
                        "detail": null,
                        "request_id": "req_8f3a4b2c",
                        "doc_url": null
                      }
                    }
                  },
                  "validationError": {
                    "summary": "Validation error",
                    "value": {
                      "error": {
                        "type": "validation",
                        "message": "Validation error",
                        "status": 400,
                        "detail": {
                          "validation": [
                            "id must be a string"
                          ]
                        },
                        "request_id": "req_8f3a4b2c",
                        "doc_url": null
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "invalidApiKey": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": {
                        "type": "invalid_token",
                        "message": "Unauthorized",
                        "status": 401,
                        "detail": null,
                        "request_id": "req_8f3a4b2c",
                        "doc_url": "https://developers.vibe.co/errors/invalid-token"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Insufficient scope error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "insufficientScope": {
                    "summary": "Missing required scope",
                    "value": {
                      "error": {
                        "type": "insufficient_scope",
                        "message": "Missing required scope",
                        "status": 403,
                        "detail": {
                          "required": "creatives:write",
                          "granted": [
                            "test"
                          ]
                        },
                        "request_id": "req_8f3a4b2c",
                        "doc_url": "https://developers.vibe.co/reference/oauth2token"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Advertiser not found"
          }
        },
        "summary": "Get presigned upload URL for a video asset",
        "tags": [
          "Creatives"
        ],
        "x-rate-limit": {
          "rps": 5,
          "rpm": 60
        },
        "x-scopes": [
          "creatives:write"
        ]
      }
    }
  },
  "info": {
    "title": "Vibe Public API",
    "description": "Vibe Public API revision 2026-06-01",
    "version": "2026-06-01",
    "contact": {}
  },
  "tags": [
    {
      "name": "Creatives",
      "description": "A Creative is the asset (video or VAST tag) that Vibe runs as part of a Strategy. Creatives belong to an Advertiser and can be associated with one or more Strategies.\n\nCreating a **video** creative is a two-step flow: request a presigned upload URL to receive a one-time S3 URL, upload the video file directly to that URL (do not proxy it through your own server), then create the video creative with the same `upload_url`.\n\nFor partners running their own ad serving, creating a VAST creative accepts a VAST tag URL directly."
    }
  ],
  "servers": [
    {
      "url": "https://api.vibe.co",
      "description": "Production API"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearer": {
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "type": "http"
      }
    },
    "schemas": {
      "ErrorDetail": {
        "type": "object",
        "properties": {
          "required": {
            "type": "string",
            "example": "audiences:write"
          },
          "granted": {
            "example": [
              "audiences:read",
              "reporting:read"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "required",
          "granted"
        ]
      },
      "ApiError": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "insufficient_scope",
              "invalid_token",
              "validation",
              "internal_error"
            ]
          },
          "message": {
            "type": "string"
          },
          "status": {
            "type": "number",
            "example": 403
          },
          "detail": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/ErrorDetail"
              }
            ]
          },
          "request_id": {
            "type": "string",
            "example": "req_8f3a4b2c"
          },
          "doc_url": {
            "type": "string",
            "example": "https://developers.vibe.co/reference/oauth2token",
            "nullable": true
          }
        },
        "required": [
          "type",
          "message",
          "status",
          "request_id"
        ]
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ApiError"
          }
        },
        "required": [
          "error"
        ]
      },
      "CreativeUploadUrl": {
        "type": "object",
        "properties": {
          "upload_url": {
            "type": "string",
            "format": "uri",
            "description": "S3 endpoint URL — POST a multipart form to this URL with the file and the returned fields."
          },
          "fields": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Presigned POST form fields (key, policy, signature, …). Include each entry as a form field of the multipart POST."
          },
          "upload_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the prepared upload. Pass it as `upload_id` when creating the creative."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "upload_url",
          "fields",
          "upload_id",
          "expires_at"
        ]
      }
    }
  },
  "security": [
    {
      "bearer": []
    }
  ]
}
```