# Quickstart

This walkthrough assumes an **API key** for one workspace. If you are building an
app that many workspaces connect to, start at [Registering an app](/apps) instead —
the calls below are the same, but you get your credential from
[OAuth](/oauth) rather than from a workspace.

## 1. Confirm your key works

```bash
export NOE_API_KEY=noe_live_...
export NOE_BASE=https://api.wearenoe.fr/v1

curl "$NOE_BASE/me" -H "Authorization: Bearer $NOE_API_KEY"
```

Check the `scopes` and `property_scope` in the response before writing anything
else. Most integration surprises are visible right here.

There is no separate sandbox: every key talks to the workspace's real data, and
calendar writes reach the connected OTAs. Build and test with read calls first,
then try your first writes on a single property the workspace agrees to use for
testing.

## 2. Read the portfolio

```bash
curl "$NOE_BASE/properties?limit=200&expand=photos" \
  -H "Authorization: Bearer $NOE_API_KEY"
```

Store each property's `id` and `updated_at`. Keep the highest `updated_at` — it
becomes your sync watermark.

## 3. Read a calendar

```bash
curl "$NOE_BASE/calendar?from=2026-09-01&to=2026-09-30&property_ids=$PROPERTY_ID" \
  -H "Authorization: Bearer $NOE_API_KEY"
```

One row per date, with price, minimum stay, arrival/departure rules and
availability already merged. `blocked_by` tells you *why* a night is
unavailable — `reservation`, `block` or `stop_sell`.

## 4. Create a block

```bash
curl -X POST "$NOE_BASE/blocks" \
  -H "Authorization: Bearer $NOE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "property_id": "'"$PROPERTY_ID"'",
    "start_date": "2026-09-10",
    "end_date": "2026-09-14",
    "reason_type": "maintenance",
    "reason": "Boiler replacement"
  }'
```

This closes the dates on the connected OTA calendars through Noé's normal sync,
so it behaves exactly like a block created by staff in the app.

Note `editable: true` on the response: you can update or delete blocks **you**
created. Blocks created by the workspace's own staff are readable but not
modifiable by an integration — you should never be able to delete an
owner's personal stay.

## 5. Update a season of pricing

One call, not ninety:

```bash
curl -X PUT "$NOE_BASE/calendar" \
  -H "Authorization: Bearer $NOE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "updates": [
      { "property_id": "'"$PROPERTY_ID"'", "from": "2026-07-01", "to": "2026-08-31",
        "price_cents": 18500, "min_stay": 3 },
      { "property_id": "'"$PROPERTY_ID"'", "from": "2026-09-01", "to": "2026-09-30",
        "price_cents": 13500, "min_stay": 2 }
    ]
  }'
```

Returns `207` with a per-item result. Check each one — a failure on range two
does not undo range one.

## 6. Switch to delta sync

Now that you have a copy, stop re-reading everything:

```bash
curl "$NOE_BASE/reservations?updated_after=2026-08-18T09:30:00Z&limit=200&expand=property" \
  -H "Authorization: Bearer $NOE_API_KEY"
```

Page with [cursors](/pagination) until `has_more` is `false`, then advance your
watermark.

## 7. Subscribe to webhooks

```bash
curl -X POST "$NOE_BASE/webhooks" \
  -H "Authorization: Bearer $NOE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://hooks.example.com/noe","events":["reservation.created","reservation.cancelled"]}'
```

Save the signing secret from the response — it is shown once. Then read
[Webhooks](/webhooks) for signature verification, which you should not skip.

## A production-ready checklist

- Branch on `error.code`, never on the message text.
- Log `request_id` on every failure; it is what support will ask for.
- Honour `Retry-After` on `429`, and retry `5xx` with backoff.
- Reuse one `Idempotency-Key` per operation across all of its retries.
- Keep an hourly `updated_after` reconciliation running alongside webhooks.
- Handle a scope disappearing: a workspace can narrow your access at any time.
