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

# Create a Case on the Fly

> Open a Penbox case from inside your own product, fill it with data, and attach a document.

A user of your product says *"open a case for Mrs Dupont"*. This guide is what happens next: a
real Penbox case appears, owned by the right person, carrying your data and your documents — and
your user never leaves your app.

## What you'll have

By the end of this guide:

* A case created from one of your templates, owned by a member of your client's team
* Its contact set to the customer the case is about
* Structured data written into it
* A document uploaded and stored on one of its fields

**Estimated time:** 10 minutes

<Info>
  Finish [Onboard a Client](/guides/headless-onboard-client) first. You need the workspace id and
  the token it returned.
</Info>

***

<Steps>
  <Step title="Find the case template">
    The templates you listed in `template_source` were copied into the workspace. Read their ids
    with [List Case Templates](/api-reference/case-templates/list-case-templates):

    ```bash theme={null}
    curl --url https://connect.penbox.io/v1/case_templates \
      --header 'Authorization: Bearer <token>'
    ```

    Cache the ids per workspace — they are stable, and you need one every time you open a case.
  </Step>

  <Step title="Create the case">
    Instantiate the template with [Create Case](/api-reference/cases/create-case):

    ```bash theme={null}
    curl --request POST \
      --url https://connect.penbox.io/v1/cases \
      --header 'Authorization: Bearer <token>' \
      --header 'Content-Type: application/json' \
      --data '{
        "title": "Dupont file",
        "workspace": { "id": "<workspace-uuid>" },
        "template": { "id": "<case-template-uuid>" },
        "owner": { "email": "amina@acme.example" },
        "contacts": [{ "key": "main", "email": "j.dupont@mail.example", "given_name": "Jean" }]
      }'
    ```

    `workspace.id` is **required** for an API token — it is never inferred. The case inherits the
    template's fields and statuses.

    <Warning>
      `owner` must be a **member** you registered in guide 1 — someone on your client's team.
      `contacts` are their **customers**, the people the case is about or the ones asked for
      documents. Swapping the two is the most common integration mistake: a contact can never own a
      case, and a member should never be invited as a contact.
    </Warning>
  </Step>

  <Step title="Push data into the case">
    Write any field of the case's schema with
    [Update Case Data](/api-reference/cases/update-case-data):

    ```bash theme={null}
    curl --request POST \
      --url https://connect.penbox.io/v1/cases/{id}/data \
      --header 'Authorization: Bearer <token>' \
      --header 'Content-Type: application/json' \
      --data '{ "data": { "policy_number": "AB-12345" } }'
    ```

    Penbox keeps the **full history** of every field: send a new value and the previous one stays
    retrievable — you never have to version data on your side. Field types and on-the-fly schema
    additions are covered in the [Data Schema](/cases/data_schema) reference.
  </Step>

  <Step title="Attach a document">
    Upload the file with
    [Upload Attachment](/api-reference/attachments/upload-attachments) — multipart or base64, up to
    10GB:

    ```bash theme={null}
    curl --request POST \
      --url https://connect.penbox.io/v1/attachments \
      --header 'Authorization: Bearer <token>' \
      --form 'file=@contract.pdf'
    ```

    The response carries the attachment's `id`. Store it in one of the case's
    [file fields](/cases/data_schema/file) by sending an array of attachment ids as the field's
    value:

    ```bash theme={null}
    curl --request POST \
      --url https://connect.penbox.io/v1/cases/{id}/data \
      --header 'Authorization: Bearer <token>' \
      --header 'Content-Type: application/json' \
      --data '{ "data": { "documents": ["<attachment-id>"] } }'
    ```

    Uploading alone does not put the file on the case — the second call is what does. Like any
    other field, a file field keeps the full history of everything ever added to it.
  </Step>
</Steps>

## You've created a case

The workspace now holds a real case:

* Built from your template, with its fields and its statuses
* Owned by a member of your client's team
* Pointing at the customer it is about
* Carrying structured data and a document, both with full history

Your user got all of that without ever leaving your product. This is the call you put behind
*"open a case for this customer"*.

**Next:** [Drive the case](/guides/headless-drive-case).
