# Release a submission (/docs/api-reference/form-submissions/release-form-submission)

Not spam: a `held` or `spam` submission becomes `accepted` and is delivered (webhooks, notifications, contacts), and Risk records its assessment as `legitimate`. Releasing an accepted submission returns it as is.

`POST https://api.coss.com/v1/forms/{id}/submissions/{submission_id}/release`

Authenticate with your API key as a bearer token (`Authorization: Bearer coss_test_…`). Responses are JSON with snake_case fields; errors are `{ error: { type, code, message, param?, issues?, request_id } }` (https://coss.com/docs/api-reference/errors.md).

## Path parameters

- `id` (string, required): The form's id.
- `submission_id` (string, required): The submission's id.

## Example request

TypeScript (the `coss` package):

```ts
import { Coss } from "coss";

const coss = new Coss({
  apiKey: process.env.COSS_API_KEY,
  baseUrl: "https://api.coss.com",
});

const { data, error } = await coss.forms.submissions.release("form_01kd2m8n3p4q5r6s7t8v9w0x1y", "fsub_01kd2m9a0b1c2d3e4f5g6h7j8k");
```

HTTP:

```sh
curl -X POST "https://api.coss.com/v1/forms/form_01kd2m8n3p4q5r6s7t8v9w0x1y/submissions/fsub_01kd2m9a0b1c2d3e4f5g6h7j8k/release" \
  -H "Authorization: Bearer $COSS_API_KEY"
```

Python:

```python
from coss import Coss

client = Coss()  # api_key= or COSS_API_KEY

client.forms.submissions.release(
    id="form_01kd2m8n3p4q5r6s7t8v9w0x1y",
    submission_id="fsub_01kd2m9a0b1c2d3e4f5g6h7j8k",
)
```

Go:

```go
import (
	"context"

	cossclient "github.com/cosscom/coss-go/client"
	forms "github.com/cosscom/coss-go/forms"
)

client := cossclient.NewClient() // option.WithAPIKey(…) or COSS_API_KEY

request := &forms.ReleaseSubmissionsRequest{
    ID: "form_01kd2m8n3p4q5r6s7t8v9w0x1y",
    SubmissionID: "fsub_01kd2m9a0b1c2d3e4f5g6h7j8k",
}
client.Forms.Submissions.Release(
    context.TODO(),
    request,
)
```

Ruby:

```ruby
require "coss"

client = Coss::Client.new # api_key: or COSS_API_KEY

client.forms.submissions.release(
  id: "form_01kd2m8n3p4q5r6s7t8v9w0x1y",
  submission_id: "fsub_01kd2m9a0b1c2d3e4f5g6h7j8k"
)
```

PHP:

```php
<?php

use Coss\Coss;

$client = new Coss(); // apiKey: or COSS_API_KEY

$client->forms->submissions->release(
    'form_01kd2m8n3p4q5r6s7t8v9w0x1y',
    'fsub_01kd2m9a0b1c2d3e4f5g6h7j8k',
);
```

Java:

```java
import com.coss.Coss;
import com.coss.resources.forms.submissions.requests.ReleaseSubmissionsRequest;

Coss client = Coss.builder().build(); // .apiKey(…) or COSS_API_KEY

client.forms().submissions().release(
    "form_01kd2m8n3p4q5r6s7t8v9w0x1y",
    "fsub_01kd2m9a0b1c2d3e4f5g6h7j8k",
    ReleaseSubmissionsRequest
        .builder()
        .build()
);
```

.NET:

```csharp
using Coss;
using Coss.Forms;

var client = new CossClient(); // apiKey: or COSS_API_KEY

await client.Forms.Submissions.ReleaseAsync(
    new ReleaseSubmissionsRequest
    {
        Id = "form_01kd2m8n3p4q5r6s7t8v9w0x1y",
        SubmissionId = "fsub_01kd2m9a0b1c2d3e4f5g6h7j8k",
    }
);
```

## Response 200

The released submission.

- `object` ("form_submission", required)
- `id` (string, required)
- `form_id` (string, required)
- `status` ("pending_confirmation" | "accepted" | "held" | "spam", required): `accepted`: delivered (webhooks, notifications, contacts). `held`: Risk asked for a review. `spam`: refused by Risk, the content check or the honeypot. `pending_confirmation`: waiting for the submitter's email link.
- `data` (map of string | string[], required): Field name → value; a field posted several times has an array.
- `submitter_email` (string | null, required)
- `files` (object[], required)
  - `id` (string, required)
  - `field` (string, required)
  - `filename` (string, required)
  - `content_type` (string, required)
  - `size` (integer, required): Bytes.
- `spam_reason` ("honeypot" | "risk_block" | "risk_review" | "content" | null, required)
- `risk` (object | null, required): Risk's assessment; `null` when none ran (honeypot).
  - `assessment_id` (string | null, required)
  - `decision` ("allow" | "review" | "block" | null, required)
  - `score` (number | null, required)
- `ip` (string | null, required)
- `user_agent` (string | null, required)
- `origin` (string | null, required)
- `referrer` (string | null, required)
- `confirmed_at` (string | null, required, date-time)
- `accepted_at` (string | null, required, date-time)
- `released_at` (string | null, required, date-time)
- `sandbox` (boolean, required)
- `created_at` (string, required, date-time)

Example:

```json
{
  "object": "form_submission",
  "id": "fsub_01kd2m9a0b1c2d3e4f5g6h7j8k",
  "form_id": "form_01kd2m8n3p4q5r6s7t8v9w0x1y",
  "status": "accepted",
  "data": {
    "name": "Ada Lovelace",
    "email": "ada@example.com",
    "message": "Hello!"
  },
  "submitter_email": "ada@example.com",
  "files": [],
  "spam_reason": null,
  "risk": {
    "assessment_id": "rsk_01kd2m9a0b1c2d3e4f5g6h7j8n",
    "decision": "allow",
    "score": 0.04
  },
  "ip": "203.0.113.7",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
  "origin": "https://www.example.com",
  "referrer": "https://www.example.com/contact",
  "confirmed_at": null,
  "accepted_at": "2026-10-29T10:00:00.000Z",
  "released_at": null,
  "sandbox": false,
  "created_at": "2026-10-29T10:00:00.000Z"
}
```

## Errors

- `400`: The `Coss-Version` header names an unknown API version (`invalid_api_version`).
- `401`: The API key is missing, invalid, revoked or expired (`authentication_error`).
- `403`: The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).
- `404`: No such form, or no submission with this id in it (`not_found`).
- `422`: Only held and spam submissions can be released (`submission_not_releasable`).
- `429`: Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).
- `500`: Unexpected server error (`api_error` / `internal_error`).
- `503`: The API key could not be verified right now; retry (`service_unavailable`).