# /forms/{formId}/fields/{fieldId}/upload-urls

Generate presigned S3 upload URLs for a file field. Upload each file directly to its returned `uploadUrl` with an HTTP PUT (bypassing the request-body size limit), then submit the matching `fileKey` as the field's `subvalue` when creating the submission. Presigned URLs expire after 2 hours.

# OpenAPI definition

```json
{
  "openapi": "3.0.0",
  "info": {
    "title": "Formstack API v2025.0",
    "version": "0.0.4"
  },
  "servers": [
    {
      "url": "https://www.formstack.com/api/v2025",
      "description": "Production server"
    },
    {
      "url": "https://staging-formstack.com/api/v2025",
      "description": "Staging server"
    },
    {
      "url": "https://dev-formstack.com/api/v2025",
      "description": "Development server"
    }
  ],
  "paths": {
    "/forms/{formId}/fields/{fieldId}/upload-urls": {
      "post": {
        "tags": [
          "Submissions",
          "Classic"
        ],
        "description": "Generate presigned S3 upload URLs for a file field. Upload each file directly to its returned `uploadUrl` with an HTTP PUT (bypassing the request-body size limit), then submit the matching `fileKey` as the field's `subvalue` when creating the submission. Presigned URLs expire after 2 hours.",
        "operationId": "createFileUploadUrls",
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "description": "The unique identifier of the form",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "fieldId",
            "in": "path",
            "description": "The file field to upload to",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileUploadUrlsInputApiDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileUploadUrlsApiDto"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request: filenames missing/empty, more than the per-field file limit, or the field is not a file field"
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Form or field not found"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "FileUploadUrlApiDto": {
        "title": "File Upload URL",
        "description": "A single presigned S3 upload target for a file field.",
        "properties": {
          "filename": {
            "description": "The original filename supplied in the request. Use this to match each upload target to the file being uploaded.",
            "type": "string"
          },
          "fileKey": {
            "description": "The S3 key to send back as the file field's `subvalue` when creating the submission.",
            "type": "string"
          },
          "uploadUrl": {
            "description": "Presigned S3 PUT URL. Upload the raw file bytes here with an HTTP PUT. Expires 2 hours after generation.",
            "type": "string",
            "format": "uri"
          }
        },
        "type": "object"
      },
      "FileUploadUrlsApiDto": {
        "title": "File Upload URLs",
        "description": "Presigned S3 upload targets for a file field. Upload each file to its `uploadUrl`, then submit the corresponding `fileKey` as the field's `subvalue` when creating the submission.",
        "properties": {
          "fieldId": {
            "description": "The file field the upload targets were generated for.",
            "type": "integer"
          },
          "fileUploads": {
            "description": "One upload target per requested filename.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FileUploadUrlApiDto"
            }
          }
        },
        "type": "object"
      },
      "FileUploadUrlsInputApiDto": {
        "title": "File Upload URLs Input",
        "description": "Request body for generating presigned S3 upload URLs for a file field.",
        "properties": {
          "filenames": {
            "description": "Original filenames to generate upload targets for. One presigned URL is returned per filename.",
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 20,
            "minItems": 1
          }
        },
        "type": "object"
      }
    }
  },
  "tags": [
    {
      "name": "Submissions",
      "description": "Submissions are the entries collected by your forms. Use these endpoints to create a submission, list submissions across all forms or for a specific form, count submissions, retrieve a single submission's data, edit or delete a submission, download uploaded files, and generate presigned URLs for direct file uploads. Results support pagination, date ranges, and field-level search."
    },
    {
      "name": "Classic",
      "description": "Classic"
    }
  ]
}
```