---
title: "Open project"
method: POST
path: "/v1/communities/{communityId}/projects/{projectId}/open"
tags: ["Projects"]
---

# Open project

`POST /v1/communities/{communityId}/projects/{projectId}/open`

## Request

- Base URL: `https://api.subo.ai`
- URL: `https://api.subo.ai/v1/communities/{communityId}/projects/{projectId}/open`
- Auth: API key in header `X-API-Key`

Activate the project for participant responses now. Project must be `inactive`. To open it later instead, set a scheduled `delivery.opening` with the update endpoint and do not call this one: the project opens itself at that time.

Optionally pass a `delivery` body to override audience, closing time, or invitation settings at the moment of opening — without a separate PUT call. All fields are optional.

The invitation is posted only where the project names a place, and today that place is a Discord channel, `delivery.invitation.post_channel_id`. A project answered on the web (`open_web`, or `private` with `response_channel` `web`) with no channel opens without posting anything: the response carries `data.share_url` for you to share and a `notice`. A project answered in Discord needs the channel and returns `422 channel_required` without one.

Go-live validation runs first, as in the Subo app: script errors block the call, and so do warnings the project has not accepted (`409 script_validation`, listing each finding). Accept a warning by passing its `fingerprint` in `acknowledge`; errors cannot be accepted and must be fixed. Run validate first to see them before the audience would.

## Path parameters

- `communityId` string, required
- `projectId` string, required

## Request body

- object
  - `delivery` object: Optional delivery overrides applied at activation time, before validation runs.
    - `audience` object
      - `participation` 'private' | 'open_web': `private`: invite-only via Discord; `open_web`: public link anyone can open
      - `response_channel` 'discord' | 'web': Where respondents complete the survey
      - `required_role_ids` string[]: Discord role snowflakes required to participate
      - `verified_source_ids` integer[]: Audience source ids (from GET /communities/{communityId}/sources) a respondent may verify with, any-of. Requires participation 'private' and response_channel 'web'.
    - `closing` object
      - `time` string, date-time, nullable: ISO 8601 datetime at which the project automatically closes
    - `answer_surfaces` string[], nullable: Ordered fallback chain of surfaces a Convo is attempted on, first to last. `null` means no override: the project follows Subo's default rules, which are resolved at press time and can differ between two posts of the same project in different channels. Send `null` to clear an override; an empty array is rejected.
    - `clear_conversation` boolean: Purge the respondent's thread transcript once they COMPLETE the Convo. Never fires on a timeout: a timed-out Convo is resumable and the respondent returns to it. Defaults to false. Only honored on a thread: Subo can bulk-delete in a thread but only its own messages in a DM, so a project with this on AND a `dm` step in `answer_surfaces` fails script validation and will not open. A web Convo carries no durable transcript, so the flag is inert there.
    - `invitation` object
      - `post_channel_id` string, nullable: Discord channel snowflake where the invitation embed is posted. For a project answered on the web (`open_web`, or `private` with `response_channel` `web`) it is the only place the invitation is posted: `null` or an empty string means post nowhere, and respondents come in through `delivery.share_url`. A project answered in Discord needs it to open. On update and open: omit to leave it, send `null` or an empty string to clear it.
      - `message` string, nullable: Custom invitation message (Markdown)
      - `thumbnail_url` string, uri, nullable
      - `image_url` string, uri, nullable: Image URL shown in the invitation embed
      - `border_color` string, nullable: 6-digit hex colour without '#' for the embed border when the project is open (e.g. `e1287e`). A leading '#' is accepted and removed; anything else is a 400.
      - `border_color_closed` string, nullable: 6-digit hex colour without '#' for the embed border when the project is closed (e.g. `745399`). A leading '#' is accepted and removed. Premium only.
      - `footer` string, nullable: Text shown below the invitation embed. Premium only.
      - `embed_config` object, nullable: Invitation embed layout — whether project info shows inline (`embed`) or behind a button, plus per-row visibility toggles
        - `info_display` 'embed' | 'button', nullable
        - `rows` object: Per-row visibility toggles for the invitation embed (open map, e.g. status/privacyMode/roles/xpReward)
      - `answer_button_label` string, nullable: Custom label for the answer/vote button. Premium only.
      - `answer_button_color` integer, nullable: Discord button style for the answer button (1 primary, 2 secondary, 3 success, 4 danger). Premium only.
  - `acknowledge` string[]: Fingerprints of script-validation warnings to accept for this project (from the validate endpoint or a `409 script_validation`). Recorded as accepted by the key's user, as in the Subo app. Errors have no fingerprint and cannot be accepted.

## Response `200`

Project activated. `data.share_url` is the respondents' web link (null for a project answered in Discord). A top-level `notice` is included when no invitation was posted.

- object
  - `data` ProjectLifecycleResponse
    - `project_id` string
    - `status` 'active' | 'inactive'
    - `share_url` string, nullable: On open: the respondents' web link, null for a project answered in Discord.
    - `notice` string, nullable: Present when the project was activated but no Discord invitation was posted

## Other responses

- `401`: Invalid or missing API key
- `402`: A Premium-only invitation override (`border_color_closed`, `footer`, `answer_button_label`, `answer_button_color`) was set on a Basic tier
- `403`: Forbidden
- `404`: Resource not found
- `409`: `conflict`: the project is already active. `script_validation`: go-live validation refused it; `errors` must be fixed, `warnings` can be accepted with `acknowledge`.
- `422`: A project answered in Discord needs a channel for its invitation: set `delivery.invitation.post_channel_id` first
- `429`: Rate limit exceeded — wait `retry_after` seconds before retrying. The same value appears in the `Retry-After` header.

---

[API](https://skmtc.dev/subo/apis/subo-api.md) · [All operations](https://skmtc.dev/subo/apis/subo-api/llms.txt) · [OpenAPI document](https://skmtc.dev/subo/apis/subo-api/revisions/12eab2ae4505?raw)
