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

# Overview

> Create and manage the businesses you serve

A **tenant** is one of your customers — a business you manage on behalf of your platform. Creating one is the first call you make against the Reach API: it returns the tenant `id` that every other tenant-scoped call, JWT, and embedded UI session refers back to.

## Identifying a tenant

A tenant has two identifiers: the Reach `id` returned by **Create Tenant**, and the `externalId` you supply — your own key for the same business. **Get**, **Update**, **Delete**, and **Reactivate** each accept either one in the path, so you never have to store the Reach `id` if you would rather look tenants up by your own.

## Lifecycle

<Steps>
  <Step title="Create">
    `POST /partner/tenants` with a name and your `externalId`. Reach provisions the tenant's default resources asynchronously, so some of them appear shortly after the response returns rather than in it.
  </Step>

  <Step title="Update">
    `PATCH /partner/tenants/{id}` — every field is optional, so send only what changed.
  </Step>

  <Step title="Deactivate">
    `DELETE /partner/tenants/{id}` deactivates rather than destroys. The tenant drops out of **List Tenants** unless you pass `includeDeleted=true`, and **Get Tenant** keeps returning it with `deletedAt` set.
  </Step>

  <Step title="Reactivate">
    `POST /partner/tenants/{id}/reactivate` restores a deactivated tenant with its data intact.
  </Step>
</Steps>

## What lives on a tenant

| Field                       | What it is for                                                                               |
| --------------------------- | -------------------------------------------------------------------------------------------- |
| `name`, `website`           | How the business is identified across Reach, and the site the tracking snippet reports from  |
| `locations`                 | The business's physical addresses                                                            |
| `branding`                  | Logo, colors, brand name, and brand voice — what the embedded UI and generated content adopt |
| `timezone`, `businessHours` | When the business is open — see below                                                        |
| `smsOptInImageUrls`         | Evidence of how the business captures SMS consent, used for carrier registration             |

<Note>
  If your partner account is configured with a location schema, the `locations` you send are stored as location resources rather than on the tenant record. Reads return them either way, so the field behaves the same from your side.
</Note>

### Merged fields and replaced fields

On update, `branding` is **merged** key by key into what is already stored, so you can send just the keys you want to change. `locations`, `smsOptInImageUrls`, and `businessHours` are **replaced wholesale** — send the complete value every time, or you will drop what you left out.

## Listing tenants

**List Tenants** is cursor-paginated through `cursor` and `limit` (default 100). Narrow it with `search`, which matches on name, external id, or website; order it with `orderBy` and `orderDirection`; include deactivated tenants with `includeDeleted=true`. For portfolio-wide sweeps, pass `fields` — a comma-separated projection such as `id,name` — to trim the payload to what you actually read.

## Timezone and business hours

`timezone` and `businessHours` record when a tenant is open. Both are accepted on **Create Tenant** and **Update Tenant**, and returned by **Get Tenant**. They sit on the business itself rather than on any one product, so one schedule serves every Reach feature that needs it — AI Voice uses `timezone` today to give the agent the tenant's local time.

You are the source of truth for both. Reach never infers a timezone from a tenant's address, and an unset value means *not configured* — it does not mean always open, and it does not mean always closed.

`timezone` is any IANA timezone id — `America/New_York`, `Europe/London`, `Pacific/Honolulu`. Send `null` to clear it.

`businessHours` is an object carrying all seven weekday keys, `monday` through `sunday`. Each key is either `null` or an empty list (closed that day), or a list holding exactly one interval of 24-hour `HH:MM` times:

```json theme={null}
{
  "monday": [{ "open": "09:00", "close": "17:00" }],
  "tuesday": [{ "open": "09:00", "close": "17:00" }],
  "wednesday": [{ "open": "09:00", "close": "17:00" }],
  "thursday": [{ "open": "09:00", "close": "17:00" }],
  "friday": [{ "open": "09:00", "close": "20:00" }],
  "saturday": [{ "open": "10:00", "close": "14:00" }],
  "sunday": null
}
```

Those are local wall-clock times in the tenant's `timezone`, never UTC. Reach reads them against the tenant's local clock at the instant it evaluates them, so daylight saving shifts resolve on their own. **The opening time is inclusive and the closing time is exclusive** — against `09:00`–`17:00`, a moment at exactly `09:00` counts as in hours, and a moment at exactly `17:00` does not.

<Warning>
  The schedule format is deliberately narrow for now:

  * **One interval per weekday.** Split shifts — a midday closure — are not supported yet.
  * **`open` must be earlier than `close`.** An interval cannot cross midnight, so overnight hours such as `20:00` to `02:00` cannot be expressed yet.
  * **All seven weekdays are required, and an update replaces the whole schedule.** There is no per-day merge: send every day on each update, and send `null` for the whole field to clear the schedule.
</Warning>

<Note>
  Tenants can also edit their own timezone and hours from the Voice settings in the embedded Reach UI. Those edits write to the same business record, so **Get Tenant** can return values you did not send. Re-read the tenant if your system needs to stay in sync.
</Note>
