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

# Forms

> API endpoints for listing, creating, updating, saving drafts, publishing, and managing form versions.

All authenticated endpoints require `Authorization: Bearer <api_key>`.

***

## List forms

```
GET /api/v2/form/
```

Returns a paginated list of all forms owned by the authenticated user.

**Response**

```json theme={null}
{
  "count": 3,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": "uuid",
      "title": "Customer feedback",
      "slug": "a1b2c3d4e5f6",
      "is_active": true,
      "has_published_version": true,
      "is_accepting_responses": true,
      "created": "2026-01-15T08:00:00Z",
      "modified": "2026-03-15T14:30:00Z"
    }
  ]
}
```

***

## Create a form

```
POST /api/v2/form/
```

**Request body**

```json theme={null}
{
  "title": "Product survey"
}
```

A `slug` is auto-generated. Returns the created form object.

***

## Get a form

```
GET /api/v2/form/{slug}/
```

Returns full form details including theme and response count.

**Response**

```json theme={null}
{
  "id": "uuid",
  "title": "Product survey",
  "slug": "a1b2c3d4e5f6",
  "theme": { "id": "uuid", "name": "Default", ... },
  "published_version": 3,
  "is_active": true,
  "is_accepting_responses": true,
  "response_limit": null,
  "total_sessions": 142,
  "created": "2026-01-15T08:00:00Z",
  "modified": "2026-03-15T14:30:00Z"
}
```

***

## Update a form

```
PATCH /api/v2/form/{slug}/
```

Updates form metadata. Accepts any subset of writable fields.

**Request body**

```json theme={null}
{
  "title": "Updated title",
  "is_accepting_responses": false,
  "response_limit": 500
}
```

***

## Delete a form

```
DELETE /api/v2/form/{slug}/
```

Soft-deletes the form (sets `is_active = false`). Returns `204 No Content`.

***

## Save a draft

```
PUT /api/v2/form/{slug}/draft/
```

Overwrites the form's current draft with a new graph. Only one draft exists per form at any time.

**Request body**

```json theme={null}
{
  "title": "Customer feedback",
  "graph": {
    "schema_version": "2.0",
    "entry_node_id": "node_welcome",
    "fallback_end_node_id": "node_end",
    "nodes": [
      {
        "id": "node_welcome",
        "question_type": "welcome_screen",
        "data": {
          "title": "Welcome!",
          "description": "This takes 2 minutes.",
          "is_required": false,
          "config": {}
        }
      },
      {
        "id": "node_q1",
        "question_type": "short_text",
        "data": {
          "title": "What is your name?",
          "is_required": true,
          "config": { "max_length": 100 }
        }
      },
      {
        "id": "node_end",
        "question_type": "end_screen",
        "data": {
          "title": "Thank you!",
          "is_required": false,
          "config": {}
        }
      }
    ],
    "edges": [
      { "from": "node_welcome", "to": "node_q1", "condition": null },
      { "from": "node_q1", "to": "node_end", "condition": null }
    ]
  }
}
```

**Response**

```json theme={null}
{
  "graph": { ... },
  "last_saved_at": "2026-03-17T10:05:30Z"
}
```

***

## Publish a form

```
POST /api/v2/form/{slug}/publish/
```

Validates the current draft and creates an immutable `FormVersion`. Returns the new version number.

**Response**

```json theme={null}
{
  "version_number": 4,
  "published_at": "2026-03-17T10:10:00Z"
}
```

Returns `400` if the draft fails validation (e.g. disconnected nodes, missing entry node).

***

## List versions

```
GET /api/v2/form/{slug}/versions/
```

**Response**

```json theme={null}
{
  "count": 4,
  "results": [
    {
      "id": "uuid",
      "version_number": 4,
      "status": "published",
      "is_valid": true,
      "published_at": "2026-03-17T10:10:00Z",
      "node_count": 8,
      "edge_count": 7,
      "is_current": true
    }
  ]
}
```

***

## Get a version

```
GET /api/v2/form/{slug}/versions/{version_number}/
```

Returns the immutable graph snapshot for a specific published version. Published versions are never modified.

***

## Next steps

<CardGroup cols={2}>
  <Card title="Sessions" icon="users" href="/developer/api-reference/sessions">
    Read respondent sessions and their traversal paths.
  </Card>

  <Card title="Responses" icon="message-square" href="/developer/api-reference/responses">
    Read individual question answers.
  </Card>
</CardGroup>
