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

# Create signed upload URL

> Issues a short-lived pre-signed PUT so the browser uploads straight to
storage, plus the public URL the object will be served from. The client
must send the same `Content-Type` on the PUT, since it is part of the
signature.

`fileSizeInBytes` is declared by the client and not enforced by the
signature — the effective cap is applied when the shortcut referencing the
file is saved.



## OpenAPI

````yaml /api/services-api.yaml post /v1/tenants/{tenantID}/uploads/signed-url
openapi: 3.0.3
info:
  description: >-
    Talqui is an omnichannel customer service platform that unifies
    conversations from WhatsApp, Instagram, Telegram, and many other channels
    into a single attendant panel, alongside a broader ecosystem of plugins and
    integrations. This API gives developers programmatic access to Talqui's
    services layer, exposing the operations needed to read and manage tenants,
    conversations, plugins, and related resources that power that platform.


    Authentication is available on behalf of an Operator (the default for this
    API), a Plugin Connection, or a Plugin — see the [Talqui authentication
    guide](https://docs.talqui.chat/guides/introduction/authentication/) for how
    each token is obtained and when to use it.


    Need help or have questions not covered here? Reach out to
    support@talqui.com.
  license:
    name: ISC
    url: https://opensource.org/license/isc-license-txt
  title: Talqui - Services API
  version: 0.65.0
servers:
  - description: Production
    url: https://services-api.talqui.chat
security: []
tags:
  - name: Tenants
  - name: Settings
  - name: Analytics
  - name: Campaigns
  - name: Campaigns models
  - name: Contacts
  - name: Handoff links
  - name: Inboxes
  - name: Messages
  - name: Notifications
  - name: Sessions
  - name: Operators
  - name: Plugins
  - name: Setup
  - name: Uploads
paths:
  /v1/tenants/{tenantID}/uploads/signed-url:
    post:
      tags:
        - Uploads
      summary: Create signed upload URL
      description: >-
        Issues a short-lived pre-signed PUT so the browser uploads straight to

        storage, plus the public URL the object will be served from. The client

        must send the same `Content-Type` on the PUT, since it is part of the

        signature.


        `fileSizeInBytes` is declared by the client and not enforced by the

        signature — the effective cap is applied when the shortcut referencing
        the

        file is saved.
      operationId: CreateSignedUploadURLController
      parameters:
        - in: path
          name: tenantID
          required: true
          schema:
            description: The tenant the upload belongs to.
            format: uuid
            pattern: >-
              ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
            type: string
      requestBody:
        content:
          application/json:
            schema:
              properties:
                fileContentType:
                  description: MIME type; must be in the supported allowlist.
                  minLength: 1
                  type: string
                fileKind:
                  description: >-
                    Upload purpose; determines the storage key prefix, the size
                    cap applied below AND whether the object is public.
                    `contact-import` is stored privately — it is a customer list
                    — and is referenced afterwards by `storageKey`, not by
                    `resourceUrl`.
                  enum:
                    - operator-shortcut
                    - support-ticket-attachment
                    - contact-import
                  type: string
                fileName:
                  description: Original file name; slugified before composing the key.
                  maxLength: 255
                  minLength: 1
                  type: string
                fileSizeInBytes:
                  description: >-
                    Declared file size in bytes; capped per `fileKind` (12 MB
                    for shortcuts, 20 MB for ticket attachments, 50 MB for
                    contact imports).
                  exclusiveMinimum: true
                  maximum: 9007199254740991
                  type: integer
              required:
                - fileKind
                - fileName
                - fileContentType
                - fileSizeInBytes
              type: object
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                additionalProperties: false
                properties:
                  expiresIn:
                    description: Seconds the pre-signed URL stays valid.
                    type: number
                  resourceUrl:
                    description: >-
                      Public URL the object is served from once the PUT
                      completes. Does not resolve for a private upload.
                    type: string
                  storageKey:
                    description: >-
                      Storage key of the object. How a private upload
                      (contact-import) is referenced afterwards.
                    type: string
                  uploadUrl:
                    description: Pre-signed PUT target. Short-lived; never persist it.
                    type: string
                required:
                  - uploadUrl
                  - resourceUrl
                  - storageKey
                  - expiresIn
                type: object
          description: Response for status 200.
        '400':
          content:
            application/json:
              schema:
                properties:
                  errors:
                    items:
                      oneOf:
                        - $ref: '#/components/schemas/MissingTenantIDError'
                        - $ref: '#/components/schemas/RequestValidationError'
                        - $ref: '#/components/schemas/UnsupportedFileTypeError'
                    maxItems: 1
                    minItems: 1
                    type: array
                required:
                  - errors
                type: object
          description: >-
            MissingTenantIDError (error_code 1001): tenantID absent from the
            URL. | RequestValidationError (error_code 1002): request body or
            params fail schema validation. | UnsupportedFileTypeError
            (error_code 1405): fileContentType outside the supported allowlist.
        '401':
          content:
            application/json:
              schema:
                properties:
                  errors:
                    items:
                      $ref: '#/components/schemas/UnauthorizedError'
                    maxItems: 1
                    minItems: 1
                    type: array
                required:
                  - errors
                type: object
          description: 'UnauthorizedError (error_code 1003): missing/invalid operator token.'
        '403':
          content:
            application/json:
              schema:
                properties:
                  errors:
                    items:
                      $ref: '#/components/schemas/ForbiddenError'
                    maxItems: 1
                    minItems: 1
                    type: array
                required:
                  - errors
                type: object
          description: 'ForbiddenError (error_code 1004): operator token rejected upstream.'
        '500':
          content:
            application/json:
              schema:
                properties:
                  errors:
                    items:
                      $ref: '#/components/schemas/UnknownError'
                    maxItems: 1
                    minItems: 1
                    type: array
                required:
                  - errors
                type: object
          description: >-
            UnknownError (error_code 5999): Unexpected internal error not
            otherwise documented for this endpoint.
      security:
        - operatorAuth: []
components:
  schemas:
    MissingTenantIDError:
      additionalProperties: false
      properties:
        error:
          enum:
            - MissingTenantIDError
          type: string
        error_code:
          enum:
            - 1001
          type: number
        message:
          example: tenantID is required.
          type: string
        statusCode:
          enum:
            - 400
          type: number
      required:
        - statusCode
        - error
        - error_code
        - message
      type: object
    RequestValidationError:
      additionalProperties: false
      properties:
        error:
          enum:
            - RequestValidationError
          type: string
        error_code:
          enum:
            - 1002
          type: number
        fields:
          items:
            additionalProperties: false
            properties:
              allowed:
                type: string
              field:
                type: string
              received:
                type: string
            required:
              - field
              - received
              - allowed
            type: object
          type: array
        message:
          example: Invalid request data.
          type: string
        statusCode:
          enum:
            - 400
          type: number
      required:
        - statusCode
        - error
        - error_code
        - message
        - fields
      type: object
    UnsupportedFileTypeError:
      additionalProperties: false
      properties:
        error:
          enum:
            - UnsupportedFileTypeError
          type: string
        error_code:
          enum:
            - 1405
          type: number
        message:
          example: This file type is not supported.
          type: string
        statusCode:
          enum:
            - 400
          type: number
      required:
        - statusCode
        - error
        - error_code
        - message
      type: object
    UnauthorizedError:
      additionalProperties: false
      properties:
        error:
          enum:
            - UnauthorizedError
          type: string
        error_code:
          enum:
            - 1003
          type: number
        message:
          example: You are not authorized to perform this request.
          type: string
        statusCode:
          enum:
            - 401
          type: number
      required:
        - statusCode
        - error
        - error_code
        - message
      type: object
    ForbiddenError:
      additionalProperties: false
      properties:
        error:
          enum:
            - ForbiddenError
          type: string
        error_code:
          enum:
            - 1004
          type: number
        message:
          example: You do not have access to this resource.
          type: string
        statusCode:
          enum:
            - 403
          type: number
      required:
        - statusCode
        - error
        - error_code
        - message
      type: object
    UnknownError:
      additionalProperties: false
      properties:
        error:
          enum:
            - UnknownError
          type: string
        error_code:
          enum:
            - 5999
          type: number
        message:
          example: For some unknown reason your request has not succeeded.
          type: string
        statusCode:
          enum:
            - 500
          type: number
      required:
        - statusCode
        - error
        - error_code
        - message
      type: object
  securitySchemes:
    operatorAuth:
      bearerFormat: JWT
      description: >-
        Behalf of an Operator (default). A JWT issued by Talqui Core when an
        operator signs in, scoped to every tenant that operator belongs to. Send
        as `Authorization: Bearer <jwt-token>`.
      scheme: bearer
      type: http

````

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