> ## Documentation Index
> Fetch the complete documentation index at: https://docs.photon.codes/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Use Stable documentation by default. Honor an explicit Beta request or a URL under /docs/beta/. If the requested version conflicts with the installed CLI package or API origin, clarify the target before writing integration code.
> Pages under /docs/beta/ document Beta; other product pages document Stable. Keep the CLI package, commands, API origin, and credentials within the selected version. State the documentation version in your answer.
> For MCP search, always pass version: Stable or version: Beta. Unfiltered search mixes both versions. For filesystem reads, keep Beta queries under /beta/ and exclude /beta/ from Stable queries; discover paths before reading them.
> The public docs base is https://photon.codes/docs. Convert MCP page paths to public URLs under that base, preserving /beta/ when present. Read https://photon.codes/docs/skill.md for version selection and https://photon.codes/docs/llms.txt for the version indexes.

# Create or get a Space

> Create or get a Space: createOrGetSpace in the TypeScript, Python, Rust and Go clients.

`POST /v1/projects/{id}/spaces`

Creates or returns a project Space. Idempotency-Key is required for every platform and binds the project, platform and initial User IDs (unordered except the iMessage creator in first position) for 24 hours after workflow completion. Concurrent matching requests join the same operation; conflicting reuse returns 422 once its outcome is available. A new email key creates a new thread; direct Spaces and SMS groups converge by participants. Every creation and successful replay requires at least one currently project-owned Agent, or for iMessage a shared-line Agent in a direct Space whose peer has an active Assignment of this project on that line. For iMessage, an existing exact match is reused; otherwise the first participant must be a project-owned dedicated phone Agent and creates the native direct chat or group. Multiple matching native groups return SPACE\_AMBIGUOUS; incomplete group membership cannot establish an exact match. Replays return 200 and the current stored Space, with Idempotent-Replayed: true. A timeout does not cancel accepted work: retry the same key and input.

**TypeScript**

```typescript TypeScript theme={null}
photon.projects.createOrGetSpace(input: CreateOrGetSpaceInput, options?: RequestOptions): Promise<CreateOrGetSpaceOutput>
```

**Python**

```python Python theme={null}
photon.projects.create_or_get_space(input: CreateOrGetSpaceInput) -> models.PlatformSpace
```

**Rust**

```rust Rust theme={null}
client.create_or_get_space(id: String, idempotency_key: String, body: &types::CreateOrGetSpaceRequest).await -> Result<ResponseValue<CreateOrGetSpaceResponse>, Error<CreateOrGetSpaceError>>
```

**Go**

```go Go theme={null}
client.Projects.CreateOrGetSpace(ctx context.Context, params *CreateOrGetSpaceParams, opts ...RequestOption) (*PlatformSpace, error)
```

```typescript TypeScript theme={null}
import { Photon } from "@photon-ai/api";

const photon = new Photon({
  headers: { Authorization: `Bearer ${process.env.PHOTON_API_TOKEN}` },
});
const result = await photon.projects.createOrGetSpace({
  path: {
    id: "id",
  },
  headers: {
    "idempotency-key": "idempotency-key",
  },
  body: {
    participantIds: [],
    platform: "sms",
  },
});
```

```python Python theme={null}
import os

from photon_api import Photon
from photon_api.rpc_generated import CreateOrGetSpaceInput

photon = Photon(headers={"Authorization": f"Bearer {os.environ['PHOTON_API_TOKEN']}"})
result = photon.projects.create_or_get_space(
    CreateOrGetSpaceInput.model_validate({
        "path": {
            "id": "id",
        },
        "headers": {
            "idempotency-key": "idempotency-key",
        },
        "body": {
            "participantIds": [],
            "platform": "sms",
        },
    })
)
```

```rust Rust theme={null}
use photon_ai_api::{Credential, PhotonClientBuilder, SecretString};

let token = std::env::var("PHOTON_API_TOKEN")?;
let client = PhotonClientBuilder::new()
    .credential("accountServiceKey", Credential::Bearer(SecretString::from(token)))
    .build()?;
let result = client
    .create_or_get_space(
        "id".to_owned(),
        "idempotency-key".to_owned(),
        &serde_json::from_value(serde_json::json!({
            "participantIds": [],
            "platform": "sms",
        }))?,
    )
    .await
    .map_err(|error| format!("{error:?}"))?
    .into_inner();
```

```go Go theme={null}
import (
	"context"
	"encoding/json"
	"os"

	photonapi "github.com/photon-hq/api/packages/go"
)

ctx := context.Background()
client := photonapi.NewClient(photonapi.WithAPIKey(os.Getenv("PHOTON_API_TOKEN")))
var body photonapi.CreateOrGetSpaceRequest
if err := json.Unmarshal([]byte(`{
	"participantIds": [],
	"platform": "sms"
}`), &body); err != nil {
	return err
}
result, err := client.Projects.CreateOrGetSpace(ctx, &photonapi.CreateOrGetSpaceParams{
	ID: "id",
	IdempotencyKey: "idempotency-key",
	Body: body,
})
if err != nil {
	return err
}
_ = result
```

```json 200 theme={null}
{
  "createdAt": "2026-01-01T00:00:00.000Z",
  "details": {},
  "id": "pho_spc_00000000000000000000000001",
  "kind": "direct",
  "metadata": {},
  "participantIds": [
    "pho_usr_00000000000000000000000001",
    "pho_usr_00000000000000000000000002"
  ],
  "platform": "whatsapp",
  "projectId": "pho_prj_00000000000000000000000001",
  "updatedAt": "2026-01-01T00:00:00.000Z"
}
```

```json 201 theme={null}
{
  "createdAt": "2026-01-01T00:00:00.000Z",
  "details": {},
  "id": "pho_spc_00000000000000000000000001",
  "kind": "direct",
  "metadata": {},
  "participantIds": [
    "pho_usr_00000000000000000000000001",
    "pho_usr_00000000000000000000000002"
  ],
  "platform": "whatsapp",
  "projectId": "pho_prj_00000000000000000000000001",
  "updatedAt": "2026-01-01T00:00:00.000Z"
}
```

## Parameters

**id** `string` *required*

**idempotency-key** `string` *required*

Required for every platform; 1-255 visible ASCII characters. Reuse for retries. For email, the same key and initial participants retrieve the same Space, and a new key starts a separate conversation. SMS identifies its Space by participants, even with a new key. iMessage binds the key to the first participant as creator and the remaining unordered User IDs. Existing matching Spaces are reused.

## Body

**participantIds** `array of string` *required*

Canonical Photon User IDs from this project and platform. iMessage uses the first participant as creator when a new chat is needed; remaining order is ignored. Other platforms ignore all participant order. Counts: iMessage 2-1000; both WhatsApp platforms exactly 2; email 1-51; SMS 2-9. Every Space requires a currently project-owned Agent.

**platform** `Platform` *required*

## Returns

**`200`** The Space already existed and is returned in its authoritative stored state. PlatformSpace

Headers: `Cache-Control`. The raw response carries these headers; see [Raw responses](https://docs.photon.codes/docs/beta/api-client/raw-responses.md).

**createdAt** `string (date-time)` *required*

When Photon first persisted this resource.

**details** `TelegramSpaceDetails` *required*

**id** `string` *required*

**kind** `string` *required*

**metadata** `ResourceMetadata` *required*

**participantIds** `array of string` *required*

**platform** `Platform` *required*

**projectId** `string` *required*

**updatedAt** `string (date-time)` *required*

When Photon last persisted a change to this resource's public state.

**`201`** The Space was created. PlatformSpace

Headers: `Cache-Control`, `Location`. The raw response carries these headers; see [Raw responses](https://docs.photon.codes/docs/beta/api-client/raw-responses.md).

**createdAt** `string (date-time)` *required*

When Photon first persisted this resource.

**details** `TelegramSpaceDetails` *required*

**id** `string` *required*

**kind** `string` *required*

**metadata** `ResourceMetadata` *required*

**participantIds** `array of string` *required*

**platform** `Platform` *required*

**projectId** `string` *required*

**updatedAt** `string (date-time)` *required*

When Photon last persisted a change to this resource's public state.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.