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

# Upload the files of a manual upload

> Second step of a manual upload, served by Transloadit rather than by Sterndesk.

Send `params` and `signature` exactly as CreateManualUpload returned them; re-serialising
`params` invalidates the signature. The files ride along in the same request under any
field name. An upload carries at most 25 files of at most 20971520 bytes each, and at
most 525336576 bytes in total.

The response is Transloadit's assembly status. Sterndesk learns of the upload through its
own notification, so nothing in the response needs to be acted on; follow the upload with
ListManualUploads instead.




## OpenAPI

````yaml https://edge.test.sterndesk.com/api/openapi.yaml post /assemblies
openapi: 3.1.0
info:
  title: Sterndesk API
  version: 1.0.0
  description: >
    HTTP/JSON access to the Sterndesk data available to your account.


    Every Sterndesk operation is a Connect RPC: send `POST <path>` with a JSON
    body and the

    `Connect-Protocol-Version: 1` header. Authenticate with a personal API key

    (Settings → My account → API keys) using `Authorization: Bearer <key>`.


    A key reads everything documented here. The one write operation is uploading
    candidate

    documents, which needs a key carrying the `sterndesk:documents:write`
    permission; permissions

    are chosen when the key is created and are never added to an existing key.
    Every other write

    operation is rejected.


    ## Uploading candidate documents


    An upload is a batch of documents, the same batch a recruiter hands to
    Sterndesk from the

    dashboard. It may hold the documents of one candidate or of several people:
    Sterndesk groups

    them by identity and creates one candidate per person. Sending them takes
    two calls.


    1. `POST /rpc/rpc.v1.OrganizationService/CreateManualUpload` creates the
    upload and returns a
       signed, time-limited instruction: `upload_url`, `params`, `signature` and `expires_at`,
       together with the limits the upload must satisfy.
    2. `POST /assemblies` sends the files to Transloadit, the upload processor,
    as
       `multipart/form-data`, with `params` and `signature` as form fields. Send both verbatim:
       the signature covers those exact bytes, so pretty-printing `params`, reordering its keys,
       or parsing and re-encoding it invalidates the signature. The files go straight to
       Transloadit and never pass through Sterndesk.

    Processing then continues asynchronously, exactly as it does for a dashboard
    upload.

    `POST /rpc/rpc.v1.OrganizationService/ListManualUploads` reports the
    progress of the upload

    created in step 1.
servers:
  - url: https://edge.sterndesk.com
security:
  - apiKey: []
tags:
  - name: rpc.v1.OrganizationService
    description: Organization service RPC for organization method.
  - name: rpc.v1.RootService
    description: RootService provides top-level RPCs.
paths:
  /assemblies:
    post:
      summary: Upload the files of a manual upload
      description: >
        Second step of a manual upload, served by Transloadit rather than by
        Sterndesk.


        Send `params` and `signature` exactly as CreateManualUpload returned
        them; re-serialising

        `params` invalidates the signature. The files ride along in the same
        request under any

        field name. An upload carries at most 25 files of at most 20971520 bytes
        each, and at

        most 525336576 bytes in total.


        The response is Transloadit's assembly status. Sterndesk learns of the
        upload through its

        own notification, so nothing in the response needs to be acted on;
        follow the upload with

        ListManualUploads instead.
      operationId: uploadManualUploadFiles
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - params
                - signature
              properties:
                params:
                  type: string
                  description: Verbatim from CreateManualUpload. Do not reformat.
                signature:
                  type: string
                  description: Verbatim from CreateManualUpload.
                files:
                  type: array
                  maxItems: 25
                  description: The documents to upload.
                  items:
                    type: string
                    format: binary
            encoding:
              files:
                contentType: >-
                  application/pdf, image/jpeg, image/png, application/msword,
                  application/vnd.openxmlformats-officedocument.wordprocessingml.document,
                  application/vnd.ms-excel,
                  application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
      responses:
        '200':
          description: Assembly created; processing continues asynchronously.
        '400':
          description: Invalid or expired signature, or a limit was exceeded.
      security: []
      servers:
        - url: https://api2.transloadit.com
components:
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: 'Personal API key, sent as `Authorization: Bearer <key>`.'

````