HomeGuidesAPI Reference
Log In
Guides

Submitting Files for Role Entities

The V3 submission endpoint supports deferred file uploads, allowing you to submit form data first and upload files separately using presigned S3 URLs. This is particularly useful for role-entity submissions where multiple entities may each have associated files.

Integration Flow

  1. Submit form data with file names (not file content)
  2. Receive presigned URLs for each file that needs uploading
  3. Upload files to S3 using the presigned URLs
  4. Confirm the submission to verify uploads and resume execution

Step 1: Submit Form Data

Submit your form data including file field values as filenames (strings).

Endpoint: POST /v3/public/actions/{token}

Example: Role-Entity Submission with Files

{
  "role-entity": [
    {
      "reference": "company_reference_id_1",
      "customer_type": "company",
      "company_name": "Acme Corporation",
      "registration_number": "12345678",
      "company_document": "registration_certificate.pdf"
    },
    {
      "reference": "owner_reference_id_1",
      "customer_type": "individual",
      "first_name": "John",
      "last_name": "Smith",
      "id_document": "passport_scan.pdf"
    }
  ],
  "role-entity_relations": [
    {
      "from": "company_reference_id_1",
      "to": "root",
      "role": "owner"
    },
    {
      "from": "owner_reference_id_1",
      "to": "company_reference_id_1",
      "role": "ubo",
      "ownership_percentage": 75
    }
  ]
}

Response (status: accepted)

When files need uploading, you receive presigned URLs:

{
  "status": "accepted",
  "fileUploads": [
    {
      "entityReference": "company_reference_id_1",
      "fileName": "registration_certificate.pdf",
      "spektrDataField": "company_document",
      "url": "https://s3.eu-north-1.amazonaws.com/bucket-name",
      "fields": {
        "key": "workspace-id/endClient/entity-id-1/registration_certificate.pdf",
        "Content-Type": "application/pdf",
        "X-Amz-Algorithm": "AWS4-HMAC-SHA256",
        "X-Amz-Credential": "...",
        "X-Amz-Date": "20260203T120000Z",
        "Policy": "eyJ...",
        "X-Amz-Signature": "..."
      }
    },
    {
      "entityReference": "owner_reference_id_1",
      "fileName": "passport_scan.pdf",
      "spektrDataField": "id_document",
      "url": "https://s3.eu-north-1.amazonaws.com/bucket-name",
      "fields": {
        "key": "workspace-id/endClient/entity-id-2/passport_scan.pdf",
        "Content-Type": "application/pdf",
        "X-Amz-Algorithm": "AWS4-HMAC-SHA256",
        "X-Amz-Credential": "...",
        "X-Amz-Date": "20260203T120000Z",
        "Policy": "eyJ...",
        "X-Amz-Signature": "..."
      }
    }
  ]
}

Response (status: completed)

When no files need uploading:

{
  "status": "completed"
}

Step 2: Upload Files to S3

For each file in the fileUploads array, send a multipart/form-data POST request to the presigned URL.

Important: Include all fields as form fields before the file content.

Example: cURL

curl -X POST "https://s3.eu-north-1.amazonaws.com/bucket-name" \
  -F "key=workspace-id/endClient/entity-id-1/registration_certificate.pdf" \
  -F "Content-Type=application/pdf" \
  -F "X-Amz-Algorithm=AWS4-HMAC-SHA256" \
  -F "X-Amz-Credential=..." \
  -F "X-Amz-Date=20260203T120000Z" \
  -F "Policy=eyJ..." \
  -F "X-Amz-Signature=..." \
  -F "file=@/path/to/registration_certificate.pdf"

Example: JavaScript/TypeScript

interface FileUploadInfo {
  entityReference?: string;
  fileName: string;
  spektrDataField: string;
  url: string;
  fields: Record<string, string>;
}

async function uploadToS3(fileUpload: FileUploadInfo, fileContent: File | Blob) {
  const formData = new FormData();
  
  // Add all presigned fields BEFORE the file
  Object.entries(fileUpload.fields).forEach(([key, value]) => {
    formData.append(key, value);
  });
  
  // Add the file content last
  formData.append('file', fileContent, fileUpload.fileName);
  
  const response = await fetch(fileUpload.url, {
    method: 'POST',
    body: formData,
  });
  
  if (!response.ok) {
    throw new Error(`Upload failed: ${response.status}`);
  }
  
  return response;
}

Step 3: Confirm Submission

After uploading all files, confirm the submission to verify uploads and resume process execution.

Endpoint: POST /v3/public/actions/{token}/confirm

Success Response (200)

{
  "status": "completed"
}

Missing Files Response (409 Conflict)

If any files are missing from S3, you'll receive new presigned URLs:

{
  "status": "pending",
  "fileUploads": [
    {
      "entityReference": "owner_reference_id_1",
      "fileName": "passport_scan.pdf",
      "spektrDataField": "id_document",
      "url": "https://s3.eu-north-1.amazonaws.com/bucket-name",
      "fields": { ... }
    }
  ]
}

Upload the missing files and call /confirm again.


Field Reference

FieldDescription
entityReferenceIdentifies which entity the file belongs to (matches reference in role-entity). Not present for non-entity submissions.
spektrDataFieldThe field name for the file (e.g., company_document, id_document)
fileNameThe original filename provided in the submission
urlThe S3 presigned URL to POST the file to
fieldsForm fields that must be included in the multipart upload

Error Handling

StatusMeaningAction
200 with status: completedNo files to uploadDone
200 with status: acceptedFiles need uploadingUpload files, then call /confirm
400Validation errorCheck error message, fix data
401Token expired/invalidRestart the flow
409 on /confirmFiles missing in S3Re-upload missing files using new URLs
500Server errorRetry or contact support

Best Practices

  1. Always check the response status - Handle both completed and accepted cases
  2. Include all fields before file - S3 presigned POST requires form fields before the file content
  3. Implement retry logic - The /confirm endpoint provides new presigned URLs if uploads fail
  4. Match entity references - Use the entityReference field to associate files with the correct entity
  5. Handle timeouts - Presigned URLs expire (typically 1 hour), so upload promptly after submission