---
title: "Create a multi-tenant form submission (v2)"
method: POST
path: "/v2/forms/submissions"
tags: ["Form Submissions"]
---

# Create a multi-tenant form submission (v2)

`POST /v2/forms/submissions`

Creates a canonical form submission and fans out practitioner/facility crosswalk creation to multiple tenants in parallel. Returns per-tenant results with an aggregated status of success, partial_success, or failed. GCS document uploads are dispatched as Cloud Tasks asynchronously.

## Headers

- `tenant-id` string, required

## Request body

- CreateMultiTenantFormSubmissionRequest — Request payload for creating a multi-tenant form submission
  - `data` unknown, required
  - `tenantIds` string[], required — List of tenant IDs to fan out to. Must contain at least one entry.
  - `options` object — Per-tenant options controlling crosswalk creation. Keys are tenant IDs. Tenants absent from this map default to createPractitioner=false and createFacility=false.

## Response `201`

Canonical form submission created. Per-tenant results in tenantResults. HTTP 201 is returned even on partial_success or failed fan-out outcomes.

- MultiTenantFormSubmissionResponse — Response for a multi-tenant form submission
  - `formSubmissionId` string — Unique identifier of the canonical form submission record
  - `status` string — Aggregated status across all tenants: success, partial_success, or failed
  - `tenantResults` TenantSubmissionResult[] — Per-tenant processing results
    - `tenantId` string — The tenant ID that was processed
    - `status` string — Processing status for this tenant: success or failed
    - `certifyId` string — Tenant crosswalk certify ID, populated when a tenant crosswalk was created. Empty string when only a portal crosswalk was created.
    - `errorCode` string, nullable — Error code when status is failed
    - `errorMessage` string, nullable — Human-readable error detail when status is failed
  - `gcsUploadStarted` boolean — Reserved for GCS document upload dispatch. Always false in this release; will reflect actual Cloud Task dispatch in a follow-up PR.

## Other responses

- `400` — Bad request: validation failure (empty tenantIds, mutual exclusion, invalid URLs, etc.)
- `401` — Unauthorized: valid JWT is required.
- `403` — Forbidden: insufficient permissions.
- `500` — Internal server error: unexpected error.
- `502` — Bad gateway: the DAL returned a null, non-object, or id-less canonical submission response.
- `503` — Service unavailable: the v2 feature is currently disabled via kill switch.

---

[API](https://skmtc.net/certifyos/apis/certify-api-layer.md) · [All operations](https://skmtc.net/certifyos/apis/certify-api-layer/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/certifyos/certify-api-layer/revisions/3d27e9019c7b/schema)
