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

# Create a location

> Add a location, with or without a street address or opening hours.

Requires `location:create` and project API access. Returns `200` and the [location resource](/api/locations/get#response-format).

<Note>Run this request with the cURL, JavaScript or PHP examples. It creates a real location; the example sets `visible` to `false` so it stays hidden from the locator.</Note>

<ParamField path="project_id" type="string" required>The public project ID.</ParamField>
<ParamField body="name" type="string" required>Location name.</ParamField>
<ParamField body="city" type="string" required>City. A street address is optional.</ParamField>
<ParamField body="address_line_1" type="string">Street address.</ParamField>
<ParamField body="address_line_2" type="string">Additional address information.</ParamField>
<ParamField body="state" type="string">State or region.</ParamField>
<ParamField body="postcode" type="string">Postal code.</ParamField>
<ParamField body="country" type="string">Country.</ParamField>
<ParamField body="lat" type="number">Latitude between -90 and 90.</ParamField>
<ParamField body="lng" type="number">Longitude between -180 and 180.</ParamField>
<ParamField body="visible" type="boolean">Whether the location is shown. Supply this explicitly when you need a particular visibility.</ParamField>
<ParamField body="hours" type="object">A full weekday schedule, or `{}` for no schedule.</ParamField>
<ParamField body="phone" type="string">Phone number.</ParamField>
<ParamField body="email" type="string">Email address.</ParamField>
<ParamField body="url" type="string">Website URL.</ParamField>

JavaScript examples run in Node.js 22 or later; PHP examples require PHP 8.2 or later with cURL. Both read `STOREROCKET_TOKEN` from your environment. See the [quickstart](/api/quickstart) for setup.

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST 'https://storerocket.io/api/v2/projects/PROJECT_ID/locations' \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    -H 'Accept: application/json' \
    -H 'Content-Type: application/json' \
    -d '{
      "name":"Coming Soon Store",
      "city":"Seattle",
      "lat":47.6062,
      "lng":-122.3321,
      "visible":false,
      "hours":{}
    }'
  ```

  ```javascript JavaScript theme={null}
  const token = process.env.STOREROCKET_TOKEN;
  if (!token) throw new Error("Set STOREROCKET_TOKEN first.");
  const projectId = "PROJECT_ID";

  const url = new URL(`https://storerocket.io/api/v2/projects/${encodeURIComponent(projectId)}/locations`);
  const response = await fetch(url, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`,
      Accept: "application/json",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      "name": "Coming Soon Store",
      "city": "Seattle",
      "lat": 47.6062,
      "lng": -122.3321,
      "visible": false,
      "hours": {}
    }),
    signal: AbortSignal.timeout(30_000),
  });

  const text = await response.text();
  if (!response.ok) throw new Error(`HTTP ${response.status}: ${text}`);
  console.log(JSON.parse(text));
  ```

  ```php PHP theme={null}
  <?php

  $token = getenv("STOREROCKET_TOKEN") ?: throw new RuntimeException("Set STOREROCKET_TOKEN first.");
  $projectId = "PROJECT_ID";

  $url = 'https://storerocket.io/api/v2/projects/' . rawurlencode($projectId) . '/locations';

  $curl = curl_init($url);
  curl_setopt_array($curl, [
      CURLOPT_CUSTOMREQUEST => "POST",
      CURLOPT_HTTPHEADER => [
          "Authorization: Bearer $token",
          "Accept: application/json",
          "Content-Type: application/json",
      ],
      CURLOPT_POSTFIELDS => json_encode([
          'name' => 'Coming Soon Store',
          'city' => 'Seattle',
          'lat' => 47.6062,
          'lng' => -122.3321,
          'visible' => false,
          'hours' => new stdClass(),
      ], JSON_THROW_ON_ERROR),
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_CONNECTTIMEOUT => 5,
      CURLOPT_TIMEOUT => 30,
  ]);

  $text = curl_exec($curl);
  $error = curl_error($curl);
  $status = (int) curl_getinfo($curl, CURLINFO_HTTP_CODE);
  curl_close($curl);

  if ($text === false) {
      throw new RuntimeException("Request failed: $error");
  }
  if ($status < 200 || $status >= 300) {
      throw new RuntimeException("HTTP $status: $text");
  }
  $data = json_decode($text, false, 512, JSON_THROW_ON_ERROR);
  echo json_encode($data, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR), PHP_EOL;
  ```
</RequestExample>

## Opening hours

Omit `hours` or send `{}` for a location without hours. You do not need to invent opening times for coming-soon locations.

A nonempty POST hours object requires **all seven weekdays**. Use short keys `mon`, `tue`, `wed`, `thu`, `fri`, `sat`, `sun`, or the corresponding full weekday names.
Values are time-range strings, `closed`, or null for an unset day:

```json theme={null}
{
  "hours": {
    "mon":"09:00-17:00",
    "tue":"09:00-17:00",
    "wed":"09:00-17:00",
    "thu":"09:00-17:00",
    "fri":"09:00-17:00",
    "sat":"10:00-14:00",
    "sun":"closed"
  }
}
```

Do not send an hours array or weekday objects containing `open`/`close` keys.

## Additional fields

| Field | Format |
| - | - |
| `slug` | Location slug |
| `address` | Full address; generated from components when needed |
| `display_address` | Address displayed to visitors |
| `timezone` | Location timezone |
| `facebook`, `instagram`, `twitter`, `yelp`, `youtube`, `tiktok` | Social profile strings |
| `filters` | Filter names as a list or comma-separated string |
| `fields` | Named custom-field object, such as `{"Manager":"Sam"}` |
| `callsToAction` | Named object, such as `{"Book":"https://example.com/book"}` |
| `location_type` | Name of a location type in the project |
| `marker_id` | Integer ID of a marker in the project |
| `cover` | Image URL or the project's stored image name |

The response's `socials` list is derived; send individual public social field names when writing.
POST can geocode synchronously when either coordinate is missing or zero. Supplying both nonzero coordinates avoids depending on a geocoding result. Zero passes validation, but POST and PUT retain this older geocoding behavior; PATCH preserves supplied zero coordinates.

Errors: `401`, `403`, `404`, `422`, `429`. Invalid input does not create a partially populated location. See [errors](/api/errors).


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