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

# Work with people

> List, create, update, archive, and restore people through Floral's public API.

Use person operations to synchronize stable profile fields and an optional active company link. List and detail responses are bounded to the public person contract.

## Prerequisites

You need `contacts:read` to list or retrieve people and `contacts:write` to create or change them. Metadata, custom fields, lifecycle changes, archive, and restore also require Work access.

Set these values once in your shell before running the examples:

```bash theme={null}
export FLORAL_BASE_URL="https://app.floral.so/api/v1"
export FLORAL_WORKSPACE="your-workspace"
export FLORAL_TOKEN="floral_pat_..."
```

Use a personal access token created for this workspace. The examples use synthetic IDs and values; replace them with values returned by your workspace.

<Warning>
  Keep `FLORAL_TOKEN` in a secret manager outside local development. Never commit it to source control or include it in logs.
</Warning>

## List people

Filter by lifecycle stage, archive status, or active company. Collections use opaque cursor pagination.

```bash theme={null}
curl --get --fail-with-body \
  --url "$FLORAL_BASE_URL/workspaces/$FLORAL_WORKSPACE/people" \
  --header "Authorization: Bearer $FLORAL_TOKEN" \
  --data-urlencode "companyId=1842" \
  --data-urlencode "status=active" \
  --data-urlencode "sort=name-asc" \
  --data-urlencode "limit=20"
```

Pass a non-null `nextCursor` back as `cursor` for the next page. Use `status=archived` to find a person before restoring them.

## Create a person

Creating a person requires a unique idempotency key. `companyId` must identify an active company in the same workspace.

```bash theme={null}
export PERSON_CREATE_KEY="01J5C4B8R3W7N2M9Q0H6K1V5TX"

curl --request POST --fail-with-body --include \
  --url "$FLORAL_BASE_URL/workspaces/$FLORAL_WORKSPACE/people" \
  --header "Authorization: Bearer $FLORAL_TOKEN" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: $PERSON_CREATE_KEY" \
  --data '{
    "name": "Ada Nielsen",
    "email": "ada.nielsen@example.com",
    "title": "Operations Director",
    "department": "Operations",
    "companyId": 1842,
    "lifecycleStage": "PROSPECT",
    "metadata": {
      "source": "partner_sync"
    },
    "customFields": {
      "preferred_language": "da"
    }
  }'
```

A successful request returns `201`, a canonical `Location`, and the new person's `ETag`.

## Apply a partial update

Retrieve the person first and copy the response `ETag`:

```bash theme={null}
curl --request GET --fail-with-body --include \
  --url "$FLORAL_BASE_URL/workspaces/$FLORAL_WORKSPACE/people/731" \
  --header "Authorization: Bearer $FLORAL_TOKEN"
```

Send only changed fields with that `ETag`. Set `companyId` to `null` to detach the current company. A `customFields` object is a typed merge patch; a null entry removes that value.

```bash theme={null}
export PERSON_ETAG='"v1.ZXhhbXBsZS1wZXJzb24"'

curl --request PATCH --fail-with-body --include \
  --url "$FLORAL_BASE_URL/workspaces/$FLORAL_WORKSPACE/people/731" \
  --header "Authorization: Bearer $FLORAL_TOKEN" \
  --header "Content-Type: application/json" \
  --header "If-Match: $PERSON_ETAG" \
  --data '{
    "title": "VP of Operations",
    "lifecycleStage": "CUSTOMER",
    "customFields": {
      "preferred_language": "en",
      "former_region": null
    }
  }'
```

Replace the saved `ETag` with the value returned by the update.

## Archive and restore

Archive a person with the current `ETag` and a unique idempotency key:

```bash theme={null}
export PERSON_ARCHIVE_KEY="01J5C4Q9D8F2R6N3M7K0W1V5TY"

curl --request POST --fail-with-body --include \
  --url "$FLORAL_BASE_URL/workspaces/$FLORAL_WORKSPACE/people/731/archive" \
  --header "Authorization: Bearer $FLORAL_TOKEN" \
  --header "Idempotency-Key: $PERSON_ARCHIVE_KEY" \
  --header "If-Match: $PERSON_ETAG"
```

Restore the same ID with the archive response's `ETag` and a new key:

```bash theme={null}
export ARCHIVED_PERSON_ETAG='"v1.ZXhhbXBsZS1hcmNoaXZlZA"'
export PERSON_RESTORE_KEY="01J5C4Z0M6T3Q8N2D7K1R5V9WX"

curl --request POST --fail-with-body --include \
  --url "$FLORAL_BASE_URL/workspaces/$FLORAL_WORKSPACE/people/731/restore" \
  --header "Authorization: Bearer $FLORAL_TOKEN" \
  --header "Idempotency-Key: $PERSON_RESTORE_KEY" \
  --header "If-Match: $ARCHIVED_PERSON_ETAG"
```

Floral protects writes with two opaque values:

* Send a unique `Idempotency-Key` when an operation requires one. Retrying the identical request with the same key replays its result for 24 hours. Within that operation, reusing the key with different canonical input returns `409 IDEMPOTENCY_CONFLICT`.
* Send the latest strong `ETag` as `If-Match` when an operation changes an existing resource. A stale value returns `412 VERSION_CONFLICT`; a missing value returns `428 PRECONDITION_REQUIRED`.

Keep the quote characters around an `ETag`, and replace your saved value after every successful write. See [Reliability and retries](/developers/api/reliability) for the complete retry rules.
