> Fetch clean Markdown by appending `.md` to any page URL under https://signalwire.com/docs or requesting it with the HTTP header `Accept: text/markdown`. The root index at https://signalwire.com/docs/llms.txt lists the available documentation indexes. # create > Create a subproject under the authenticated root project. ### projects.create Create a subproject under the authenticated root project. ### Schema ```yaml openapi: 3.1.0 info: title: API version: 1.0.0 paths: /api/projects: post: operationId: subpackageProjects_create_subproject summary: Create a project description: >- Creates a project. Which kind depends on the credential: - With a **project API token**, the new project is always a subproject of the authenticated root project, and `parent_project_id` is ignored. Creating while authenticated as a subproject fails with `422 nested_subprojects_not_allowed`, since a subproject cannot contain subprojects. - With a **Personal access token**, omit `parent_project_id` to create a root project, or set it to create a subproject of that project. The parent must be a root project the token holder can reach (`invalid_parent_project_id`, `nested_subprojects_not_allowed`). A new root project has no API token yet. Give it one with [Create API token](/docs/apis/rest/project-tokens/create-token), passing its id as `project_id`. The response includes the `signing_key`. This is the only time it is returned — it cannot be retrieved through the API afterward, so capture it from this response. Use a subproject to isolate settings and resources beneath a root project. Integrations built around Compatibility API Account SIDs can use [Create subprojects](/docs/compatibility-api/rest/accounts/create-subprojects) instead. #### Permissions With a project API token, the token must have the following scope(s) enabled to make a successful request: _Management_. With a [Personal access token](/docs/apis/authorization#personal-access-tokens) there are no scopes. The token holder must be an owner or admin of the space, and the request reaches only the projects the holder is enabled for, plus their subprojects. [Learn more about API scopes](/docs/platform/your-signalwire-api-space). tags: - subpackage_projects responses: '201': description: >- The request has succeeded and a new resource has been created as a result. content: application/json: schema: $ref: '#/components/schemas/Projects.ProjectWithSigningKey' '401': description: Access is unauthorized. content: application/json: schema: $ref: '#/components/schemas/Types.StatusCodes.StatusCode401' '422': description: >- The request could not be processed. Creating while authenticated as a subproject, or naming a subproject as `parent_project_id`, returns `nested_subprojects_not_allowed`. A `parent_project_id` the caller cannot reach returns `invalid_parent_project_id`. A blank or overly long `name` returns a standard validation error. content: application/json: schema: $ref: '#/components/schemas/Projects.CreateProjectStatusCode422' '500': description: An internal server error occurred. content: application/json: schema: $ref: '#/components/schemas/Types.StatusCodes.StatusCode500' requestBody: content: application/json: schema: $ref: '#/components/schemas/Projects.CreateProjectRequest' tags: - name: subpackage_projects servers: - url: https://%7BYour_Space_Name%7D.signalwire.com description: SignalWire API components: schemas: uuid: type: string format: uuid description: Universal Unique Identifier. title: uuid Projects.CreateProjectRequest: type: object properties: name: type: string maxLength: 250 description: The name of the project. parent_project_id: $ref: '#/components/schemas/uuid' description: >- Personal access token only. The root project to create the new project under. Omit it to create a root project. Must name a root project the token holder can reach (`invalid_parent_project_id`, `nested_subprojects_not_allowed`). Ignored with a project API token, which always creates a subproject of its own project. protect_recordings: type: boolean description: >- When enabled, recordings created within the project require authentication to access. protect_message_media: type: boolean description: >- When enabled, message media created within the project requires authentication to access. protect_fax_media: type: boolean description: >- When enabled, fax media created within the project requires authentication to access. force_https_requests: type: boolean description: >- When enabled, requests made to the project's webhooks and callbacks must use HTTPS. required: - name description: Request body for creating a project. title: Projects.CreateProjectRequest Projects.ProjectWithSigningKey: type: object properties: id: $ref: '#/components/schemas/uuid' description: The unique identifier of the project. name: type: string description: The name of the project. parent_project_id: oneOf: - $ref: '#/components/schemas/uuid' - type: 'null' description: >- The unique identifier of the root project. `null` when this project is itself a root project. subproject: type: boolean description: '`true` when this project is a subproject.' region_preference: type: string description: >- The effective region preference for the project. Returned in all responses; it is not currently settable through this API. protect_recordings: type: boolean description: >- When enabled, recordings created within the project require authentication to access. protect_message_media: type: boolean description: >- When enabled, message media created within the project requires authentication to access. protect_fax_media: type: boolean description: >- When enabled, fax media created within the project requires authentication to access. force_https_requests: type: boolean description: >- When enabled, requests made to the project's webhooks and callbacks must use HTTPS. created_at: type: string format: date-time description: The date and time when the project was created. updated_at: type: string format: date-time description: The date and time when the project was last updated. signing_key: type: string description: >- The project's signing key. Only returned on create and signing-key rotation responses; it cannot be retrieved through the API afterward. required: - id - name - parent_project_id - subproject - region_preference - protect_recordings - protect_message_media - protect_fax_media - force_https_requests - created_at - updated_at - signing_key description: >- A project, including its `signing_key`. The `signing_key` is only returned when creating a subproject or rotating a project's signing key. It is not retrievable afterward, so capture it from the response. title: Projects.ProjectWithSigningKey TypesStatusCodesStatusCode401Error: type: string enum: - Unauthorized title: TypesStatusCodesStatusCode401Error Types.StatusCodes.StatusCode401: type: object properties: error: $ref: '#/components/schemas/TypesStatusCodesStatusCode401Error' required: - error description: Access is unauthorized. title: Types.StatusCodes.StatusCode401 Types.StatusCodes.RestApiErrorItem: type: object properties: type: type: string description: The category of error. code: type: string description: A specific error code. message: type: string description: A description of what caused the error. attribute: type: - string - 'null' description: The request parameter that caused the error, if applicable. url: type: string description: A link to documentation about this error. required: - type - code - message - url description: Details about a specific error. title: Types.StatusCodes.RestApiErrorItem Projects.CreateProjectStatusCode422: type: object properties: errors: type: array items: $ref: '#/components/schemas/Types.StatusCodes.RestApiErrorItem' description: List of validation errors. required: - errors description: >- The request could not be processed. Creating while authenticated as a subproject, or naming a subproject as `parent_project_id`, returns `nested_subprojects_not_allowed`. A `parent_project_id` the caller cannot reach returns `invalid_parent_project_id`. A blank or overly long `name` returns a standard validation error. title: Projects.CreateProjectStatusCode422 TypesStatusCodesStatusCode500Error: type: string enum: - Internal Server Error title: TypesStatusCodesStatusCode500Error Types.StatusCodes.StatusCode500: type: object properties: error: $ref: '#/components/schemas/TypesStatusCodesStatusCode500Error' required: - error description: An internal server error occurred. title: Types.StatusCodes.StatusCode500 ``` ## Parameters All parameters are keyword-only. **`name`** `str` — required Display name for the subproject. --- **`protect_recordings`** `bool | None` — default: None Require authentication to download call recordings. --- **`protect_message_media`** `bool | None` — default: None Require authentication to download message media. --- **`protect_fax_media`** `bool | None` — default: None Require authentication to download fax media. --- **`force_https_requests`** `bool | None` — default: None Reject webhook URLs that aren't HTTPS. --- **`extras`** `Mapping[str, Any] | None` — default: None Additional request body fields merged into the payload as sent. --- **`request_options`** `RequestOptions | None` — default: None Per-call timeout and retry overrides. See [`RequestOptions`](/docs/server-sdks/reference/python/rest/request-options). --- ## Returns `Project` — the new subproject. The response also carries `signing_key`, which is returned only on creation and by `rotate_signing_key`, so store it now. ## Response Example ### Response (201) ```json { "id": "8f14e45f-ceea-467d-9c2b-7a1d3a9b2c34", "name": "Acme Staging", "parent_project_id": "b3877739-5c7e-4d4f-9d1a-2f0c8c2f1a11", "subproject": true, "region_preference": "us-west", "protect_recordings": false, "protect_message_media": false, "protect_fax_media": false, "force_https_requests": true, "created_at": "2024-05-06T12:20:00Z", "updated_at": "2024-05-06T12:20:00Z", "signing_key": "PSK_4d8c2b1a9f3e7c6d5b4a3e2f1d0c9b8a" } ``` ## Example ```python {9} from signalwire.rest import RestClient client = RestClient( project="your-project-id", token="your-api-token", host="your-space.signalwire.com", ) sub = client.projects.create( name="Bayview Taxi - staging", protect_recordings=True, force_https_requests=True, ) print(sub["id"]) ``` > Create a subproject under the authenticated root project.