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

# Get a file upload URL

> Get a single-use presigned URL to upload a customer's identity documents



## OpenAPI

````yaml POST /platform/v1/customers/{id}/files/upload-url
openapi: 3.1.0
info:
  title: MoonPay
  version: 1.0.0
servers:
  - url: https://api.moonpay.com
    description: Production Environment
    variables: {}
  - url: https://api.moonpay.dev
    description: Sandbox Environment
    variables: {}
security: []
tags:
  - name: Assets
  - name: Quote
  - name: Customer
  - name: Identity
  - name: Transactions
paths:
  /platform/v1/customers/{id}/files/upload-url:
    post:
      tags:
        - Customer
      summary: Issue a presigned URL to upload a customer's identity-related file
      description: >-
        Issues a single-use presigned URL the partner can use to upload an
        identity-related file directly to MoonPay storage. The returned URL is
        valid for 15 minutes.
      operationId: CustomersController.getUploadUrl
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IdentityFileUploadUrlRequestBody'
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/IdentityFileUploadUrl'
                required:
                  - data
                unevaluatedProperties:
                  not: {}
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DevPlatformApiErrorResponse'
        '401':
          description: Access is unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DevPlatformApiErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConflictError'
      security:
        - AccessTokenAuth: []
        - SecretApiKeyInHeaderAuth: []
components:
  schemas:
    IdentityFileUploadUrlRequestBody:
      type: object
      required:
        - fileType
        - mimeType
      properties:
        fileType:
          allOf:
            - $ref: '#/components/schemas/IdentityFileType'
          description: Type of file the customer is uploading.
        side:
          allOf:
            - $ref: '#/components/schemas/IdentityFileSide'
          description: >-
            Side of the document being uploaded. Required for two-sided file
            types (`drivingLicence`, `nationalIdentityCard`, `residencePermit`);
            must be omitted for single-sided file types.
        mimeType:
          allOf:
            - $ref: '#/components/schemas/IdentityFileMimeType'
          description: >-
            MIME type of the file being uploaded. Must match the `Content-Type`
            header used on the subsequent upload request.
        sourceOfWealth:
          allOf:
            - $ref: '#/components/schemas/SourceOfWealth'
          description: >-
            Source of wealth the file evidences. Required for `proofOfIncome`;
            must be omitted for all other file types.
        subtype:
          allOf:
            - $ref: '#/components/schemas/FileSubtype'
          description: >-
            Document subtype. Required for `proofOfIncome` and must be permitted
            for the declared `sourceOfWealth`; must be omitted for all other
            file types.
      unevaluatedProperties:
        not: {}
      description: >-
        Request body for issuing a presigned upload URL for an identity-related
        file.
    IdentityFileUploadUrl:
      type: object
      required:
        - uploadId
        - url
        - expiresAt
        - headers
      properties:
        uploadId:
          type: string
          description: >-
            Identifier of the upload. Use this value to refer to the file in
            subsequent submission calls.
        url:
          type: string
          description: >-
            Fully-formed presigned URL. PUT the file body to this URL using the
            headers in `headers` within the validity window expressed by
            `expiresAt`.
        expiresAt:
          type: string
          format: date-time
          description: >-
            Timestamp at which the presigned URL expires. Partners must complete
            the upload before this time.
        headers:
          allOf:
            - $ref: '#/components/schemas/IdentityFileUploadUrlHeaders'
          description: Headers the partner must set on the upload request.
      unevaluatedProperties:
        not: {}
      description: >-
        Presigned URL the partner uses to upload an identity-related file
        directly to MoonPay storage.
    DevPlatformApiErrorResponse:
      type: object
      required:
        - code
        - message
      properties:
        code:
          allOf:
            - $ref: '#/components/schemas/DevPlatformApiErrorCodes'
          description: Code identifying the error type.
          examples:
            - forbidden
            - unauthorized
            - invalid_request
        message:
          type: string
          description: Human-readable error message.
          examples:
            - Forbidden
            - Not authorized
            - One or more request parameters are invalid.
        errors:
          type: array
          items:
            $ref: '#/components/schemas/DevPlatformErrorDetail'
          description: Optional list of field-level error details.
          examples:
            - - field: source.amount
                message: >-
                  Source amount must be a numeric string. Example "100" or
                  "10.25".
      unevaluatedProperties:
        not: {}
      description: Response body returned when a request fails.
    UnauthorizedError:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          enum:
            - unauthorized
        message:
          type: string
          enum:
            - Not authorized
      unevaluatedProperties:
        not: {}
      description: Missing or invalid credentials.
    ForbiddenError:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          enum:
            - forbidden
        message:
          type: string
          enum:
            - Forbidden
      unevaluatedProperties:
        not: {}
      description: Insufficient permissions.
    ConflictError:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          enum:
            - conflict
        message:
          type: string
          enum:
            - Conflict
      unevaluatedProperties:
        not: {}
      description: The request conflicts with the current customer state.
    IdentityFileType:
      type: string
      enum:
        - drivingLicence
        - nationalIdentityCard
        - passport
        - residencePermit
        - selfie
        - proofOfAddress
        - proofOfIncome
      description: Type of identity-related file the customer is uploading.
    IdentityFileSide:
      type: string
      enum:
        - front
        - back
      description: Side of a two-sided identity document being uploaded.
    IdentityFileMimeType:
      type: string
      enum:
        - image/jpeg
        - image/png
        - application/pdf
      description: MIME type of the file being uploaded.
    SourceOfWealth:
      type: string
      enum:
        - salary
        - savings
        - investments
        - cryptoTrading
        - companyProfits
        - companySale
        - propertySale
        - soleProprietorIncome
        - rentalIncome
        - inheritance
        - pension
      description: Source of wealth a proof-of-income file evidences.
    FileSubtype:
      type: string
      enum:
        - payslip
        - bankStatement
        - accountScreenshot
        - companyRegisterScreenshot
        - dividendDistributionCertificate
        - investmentPortfolioStatement
        - invoice
        - pensionStatement
        - rentalAgreement
        - saleContract
        - signedLetterFromSolicitorOrTrustee
      description: >-
        Subtype of a proof-of-income document. Must be permitted for the
        declared `sourceOfWealth`.
    IdentityFileUploadUrlHeaders:
      type: object
      required:
        - Content-Type
      properties:
        Content-Type:
          type: string
          description: Content-Type header value. Must match the `mimeType` requested.
          examples:
            - image/jpeg
      unevaluatedProperties:
        not: {}
      description: >-
        Headers the partner must send when uploading the file to the presigned
        URL.
    DevPlatformApiErrorCodes:
      type: string
      enum:
        - unknown_error
        - unauthorized
        - forbidden
        - not_found
        - invalid_request
        - not_implemented
        - too_many_requests
        - not_allowed
        - conflict
        - unprocessable_entity
        - sse_timeout
        - sse_error
        - service_unavailable
        - requirements_incomplete
        - requirement_not_pending
        - verification_rejected
        - country_mismatch
        - upload_expired
        - unsupported_country
        - verification_pending
        - kyc_not_approved
        - no_outstanding_requirements
        - terms_accepted_at_out_of_range
    DevPlatformErrorDetail:
      type: object
      required:
        - message
      properties:
        field:
          type: string
          description: Field that caused the error.
        message:
          type: string
          description: Human-readable error message for this field.
        details:
          type: object
          unevaluatedProperties: {}
          description: >-
            Extra data that describes the error in more detail, useful when
            debugging or logging. Keys vary by error and are not part of the API
            contract. For example, an amount-limit error includes the limit
            value as "maxBuyAmount" or "minBuyAmount".
      unevaluatedProperties:
        not: {}
  securitySchemes:
    AccessTokenAuth:
      type: http
      scheme: bearer
      description: |-
        Bearer authentication header using an access token.

        Example: `Authorization: Bearer <accessToken>`
    SecretApiKeyInHeaderAuth:
      type: apiKey
      in: header
      name: X-Api-Key
      description: |-
        Secret key authentication via the `X-Api-Key` header.

        Example: `X-Api-Key: <secretKey>`

````