> ## 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.

# Create Location Resource

> Creates a single location resource using the default location schema.



## OpenAPI

````yaml POST /api/resources/locations
openapi: 3.1.0
info:
  title: Reach API
  version: 1.0.0
  description: API documentation for Reach platform
servers:
  - url: https://api.embedreach.com
    description: Production server
security: []
tags:
  - name: Default Partner Resources
    x-reach-introduction: >-
      ---

      title: 'Default Partner Resources'

      description: 'Convenience endpoints for default resource schemas'

      ---


      Reach provides three default resource schemas that are available to
      partners upon request: **customers**, **locations**, and **transactions**.
      These schemas come pre-configured with common fields and can be used
      immediately once enabled for your partner account.


      <Note>
        These default schemas can be customized to match your specific data structure. See [Schema Definitions](/api-reference/endpoint/get-partner-schema-definitions) for information on customizing or creating your own schemas.
      </Note>


      ## Available Default Schemas


      - **customers**: For storing customer/user data

      - **locations**: For storing business location data  

      - **transactions**: For storing transaction/order data


      ## Using Default Resource Endpoints


      The endpoints in this section provide convenient shortcuts for all CRUD
      operations on the default resource schemas. These endpoints are equivalent
      to using the generic [Partner
      Resources](/api-reference/endpoint/get-api-resources-schemadefinitionnameorid)
      endpoints with the schema name (`customers`, `locations`, or
      `transactions`).


      Operations supported:

      - **Create**: Single and batch upload

      - **Read**: List all resources or get by external ID

      - **Update**: Patch single resource or batch patch

      - **Delete**: Delete single resource or batch delete
  - name: Schema Definitions
    x-reach-introduction: >-
      ---

      title: 'Overview'

      description: 'Define the shape of your data before you send it'

      ---


      A **schema definition** describes your data as it exists in your system —
      a JSON Schema for your customers, transactions, locations, or any custom
      record type. These endpoints let you create, read, update, and list those
      definitions. Defining a schema is self-service; you don't need to wait on
      Reach to do it for you.


      <Note>

      **New to this? Read the concepts first — they'll save you a redesign.**
      Schema definitions are one half of a two-part model, and the shape you
      choose here determines what your tenants can segment and message on later.


      - [How Reach models your data](/data-sharing/data-model) — the three
      canonical concepts (contact, transaction, location), and the
      definition-vs-mapping distinction.

      - [Custom Schemas](/data-sharing/custom-schemas) — the JSON Schema format,
      `$ref` references between schemas, categories, and PII annotations.

      - [Data Sync Setup](/onboarding/data-sync-setup) — how defining schemas
      fits into onboarding.

      </Note>


      A definition on its own is just a shape Reach stores. To turn it into a
      contact, transaction, or location, pair it with a [Schema
      Mapping](/api-reference/endpoint/get-partner-schema-mappings).


      <Warning>

      Validation is strict, and it protects existing data: you can always
      **add** fields, but **removing, renaming, or retyping** a field that
      resources already use is restricted, and fields that live tenant segments
      or merge fields depend on are protected. Iterate freely before go-live; be
      deliberate after.

      </Warning>
  - name: Schema Mappings
    x-reach-introduction: >-
      ---

      title: 'Overview'

      description: 'Tell Reach how to read your data as its core concepts'

      ---


      A **schema mapping** tells Reach how to interpret your [schema
      definitions](/api-reference/endpoint/get-partner-schema-definitions) in
      terms of its three canonical concepts — **contact**, **transaction**, and
      **location**. It's the step that says "the `email` field on this schema is
      the contact's email," "this schema is a `transactions_schema` and
      `transactionTotal` is the amount," and so on.


      <Note>

      **Definition vs. mapping is the distinction partners most often trip on —
      read this before you map.**


      - A **definition** is *the shape of your data* (your field names, your
      structure).

      - A **mapping** is *how Reach reads that shape as its concepts*.


      Two steps, two parts of the UI. Start here:


      - [How Reach models your data](/data-sharing/data-model) — the concepts
      and the definition-vs-mapping split.

      - [Custom Schemas → Partner Schema
      Mappings](/data-sharing/custom-schemas#partner-schema-mappings) — the full
      mapping field reference for contacts, transactions, and locations.

      </Note>


      Define your schemas first, then map them. A mapping references a schema
      definition by ID, so the definition must exist before you can map it.
  - name: Tenants
    x-reach-introduction: >-
      ---

      title: 'Overview'

      description: '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

      {
        "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>
paths:
  /api/resources/locations:
    post:
      tags:
        - Default Partner Resources
      summary: Create Location Resource
      description: Creates a single location resource using the default location schema.
      parameters:
        - name: reach-tenant-id
          in: header
          required: false
          schema:
            type: string
            description: >-
              If using a platform scoped JWT, you can pass in a header to
              impersonate a specific tenant to impersonate the request as.
        - schema:
            type: string
            enum:
              - upsert
              - reject
            default: upsert
            description: >-
              What to do if the resource already exists. upsert will merge new
              data with existing data (PATCH-like behavior), preserving existing
              fields not included in the request. Null values will delete
              fields. reject will throw an error if the resource already exists
          required: false
          description: >-
            What to do if the resource already exists. upsert will merge new
            data with existing data (PATCH-like behavior), preserving existing
            fields not included in the request. Null values will delete fields.
            reject will throw an error if the resource already exists
          name: onconflict
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            default: 'false'
            description: >-
              Whether to allow extra fields that are not defined in the schema.
              If true, extra fields will be accepted but not saved. If false,
              requests with extra fields will be rejected.
          required: false
          description: >-
            Whether to allow extra fields that are not defined in the schema. If
            true, extra fields will be accepted but not saved. If false,
            requests with extra fields will be rejected.
          name: ignoreUnknownFields
          in: query
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  type: object
                  properties:
                    locationId:
                      type: string
                    name:
                      type: string
                    address:
                      type: string
                      description: Primary address line
                    address2:
                      type: string
                      description: Secondary address line (apartment, suite, etc.)
                    address3:
                      type: string
                      description: Additional address line
                    city:
                      type: string
                    state:
                      type: string
                    zipCode:
                      type: string
                  required:
                    - locationId
                    - name
                    - address
                    - city
                    - state
                    - zipCode
                  description: Default Location Resource
              required:
                - data
      responses:
        '200':
          description: Status 200 response
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                        description: Unique identifier for the resource
                      schema_definition_id:
                        type: string
                        format: uuid
                        description: >-
                          [Deprecated] Please use schemaDefinitionId instead. ID
                          of the schema definition for this resource
                      schemaDefinitionId:
                        type: string
                        format: uuid
                        description: ID of the schema definition for this resource
                      platform_id:
                        type: string
                        format: uuid
                        description: >-
                          [Deprecated] Please use platformId instead. ID of the
                          platform this resource belongs to
                      platformId:
                        type: string
                        format: uuid
                        description: ID of the platform this resource belongs to
                      business_id:
                        type: string
                        format: uuid
                        description: >-
                          [Deprecated] Please use businessId instead. ID of the
                          business this resource belongs to
                      businessId:
                        type: string
                        format: uuid
                        description: ID of the business this resource belongs to
                      resource_external_id:
                        type: string
                        description: External ID of the resource
                      resourceExternalId:
                        type: string
                        description: >-
                          [Deprecated] Please use resourceExternalId instead.
                          External ID of the resource
                      created_at:
                        type: string
                        description: '[Deprecated] Please use createdAt instead'
                      createdAt:
                        type: string
                        description: Creation timestamp
                      updated_at:
                        type: string
                        description: '[Deprecated] Please use updatedAt instead'
                      updatedAt:
                        type: string
                        description: Last update timestamp
                      data:
                        type: object
                        properties:
                          locationId:
                            type: string
                          name:
                            type: string
                          address:
                            type: string
                            description: Primary address line
                          address2:
                            type: string
                            description: Secondary address line (apartment, suite, etc.)
                          address3:
                            type: string
                            description: Additional address line
                          city:
                            type: string
                          state:
                            type: string
                          zipCode:
                            type: string
                        required:
                          - locationId
                          - name
                          - address
                          - city
                          - state
                          - zipCode
                    required:
                      - id
                      - schema_definition_id
                      - schemaDefinitionId
                      - platform_id
                      - platformId
                      - business_id
                      - businessId
                      - resource_external_id
                      - resourceExternalId
                      - created_at
                      - createdAt
                      - updated_at
                      - updatedAt
                      - data
                required:
                  - success
        '400':
          description: Bad Request - Validation or request error
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                    default: false
                  message:
                    type: string
                    description: Error message describing what went wrong
                  errors:
                    type: array
                    items:
                      type: string
                    description: Optional array of specific validation errors
                required:
                  - message
        '404':
          description: Status 404 response
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
                  data:
                    type: object
                    properties:
                      error:
                        type: string
                    required:
                      - error
                required:
                  - success

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.