# Location

## Request location sharing

`chats.location.request(strchat_id)  -> LocationRequestResponse`

**post** `/v3/chats/{chatId}/location/request`

Request a contact in a chat to share their location. They receive an iMessage
prompt and must accept before any location is available; once they do, read their
location coordinates with `GET /v3/chats/{chatId}/location`.

The request is delivered asynchronously. The endpoint returns immediately with
`{ "success": true, "message": "Location request sent" }` and does not return
coordinates.

Rejected with `409` if the recipient is already sharing — read their
location with `GET /v3/chats/{chatId}/location` instead of re-requesting.

Rate limited per chat, since each request prompts the recipient's device.
Exceeding it returns `429` with a `Retry-After` header.

Location requests only work in **1:1 iMessage chats** (Apple limitation):

- Group chats (any service) return `409` with code `2016`
  (`GroupChatNotSupported`).
- 1:1 SMS and RCS chats return `409` with code `2017`
  (`ChatServiceNotSupported`).

### Parameters

- `chat_id: str`

### Returns

- `class LocationRequestResponse: …`

  - `message: str`

  - `success: bool`

### Example

```python
import os
from linq import LinqAPIV3

client = LinqAPIV3(
    api_key=os.environ.get("LINQ_API_V3_API_KEY"),  # This is the default and can be omitted
)
location_request_response = client.chats.location.request(
    "975d0776-bd17-4273-8337-f346b4c661b0",
)
print(location_request_response.message)
```

#### Response

```json
{
  "success": true,
  "message": "Location request sent"
}
```

## Get location data

`chats.location.retrieve(strchat_id)  -> GetChatLocationResponse`

**get** `/v3/chats/{chatId}/location`

Retrieve the current location for contacts sharing with you in a chat.

The response is wrapped in the standard `{ "success": true, "data": ... }` envelope —
the body is **not** a bare GeoJSON document. `data` is a
[GeoJSON](https://datatracker.ietf.org/doc/html/rfc7946) `FeatureCollection` with a
`Feature` for each participant actively sharing their location.

Works for both 1:1 and group chats. In group chats, `data.features` contains a separate
feature for each participant who is sharing. Each feature's `properties.handle` identifies the user.

A participant appears as soon as their first position arrives, typically
within a second or two of sharing starting.

Returns an empty `data.features` array if no one is sharing or no location data is
available yet. If sharing started but this stays empty, see the **Location Sharing**
overview.

Poll this endpoint to track a moving contact. `properties.updated_at`
reflects when each participant's location was last updated. There is no
coordinate-update webhook. See the **Location Sharing** overview for polling
guidance.

### Parameters

- `chat_id: str`

### Returns

- `class GetChatLocationResponse: …`

  - `data: Data`

    - `features: List[DataFeature]`

      - `geometry: DataFeatureGeometry`

        - `coordinates: List[float]`

          [longitude, latitude]

        - `type: Literal["Point"]`

          - `"Point"`

      - `properties: DataFeatureProperties`

        - `handle: str`

          Phone number or email of the person sharing their location

        - `address: Optional[str]`

          Full street address

        - `locality: Optional[str]`

          City or locality name

        - `updated_at: Optional[datetime]`

          When the location was last updated

      - `type: Literal["Feature"]`

        - `"Feature"`

    - `type: Literal["FeatureCollection"]`

      - `"FeatureCollection"`

  - `success: bool`

### Example

```python
import os
from linq import LinqAPIV3

client = LinqAPIV3(
    api_key=os.environ.get("LINQ_API_V3_API_KEY"),  # This is the default and can be omitted
)
get_chat_location_response = client.chats.location.retrieve(
    "975d0776-bd17-4273-8337-f346b4c661b0",
)
print(get_chat_location_response.data)
```

#### Response

```json
{
  "error": {
    "status": 400,
    "code": 1002,
    "message": "Phone number must be in E.164 format",
    "doc_url": "https://docs.linqapp.com/channel/imessage/error/codes/1xxx/1002/"
  },
  "success": false
}
```

## Stop location sharing

`chats.location.stop(strchat_id, LocationStopParams**kwargs)  -> StopChatLocationSharingResponse`

**delete** `/v3/chats/{chatId}/location`

End the location share a contact started with you, as though they had stopped it
themselves. Their device stops listing you as someone they share with, so they can
start a fresh share cleanly.

Use this to recover when a share has gone stale — coordinates that stop advancing, or
a share you believe has ended but is still reported as active. Without it the only
remedy is asking the contact to stop and re-share, which is confusing for them because
their phone still shows everything as working.

This is not reversible from the API. Sharing can only resume when the contact starts a
new share, so prompt them to re-share afterwards. Request a new one with
`POST /v3/chats/{chatId}/location/request`.

Apple keeps one location-sharing relationship per person rather than per chat, so this
ends that contact's share everywhere, not only in this chat.

`handle` names whose share to end, and is always required — a group chat can have several
people sharing, and this is not an operation to infer a target for.

**This returns `202`, not `200`.** The removal happens on the device that holds the
sharing relationship, so a success here means the request was accepted, not that
sharing has ended. Wait for the `location.sharing.stopped` webhook to confirm it —
that webhook is what tells you the contact's device has actually let go.

Returns `404` if the contact is not currently sharing.

### Parameters

- `chat_id: str`

- `handle: str`

  Phone number (E.164 format) or email address of the contact whose share to end

### Returns

- `class StopChatLocationSharingResponse: …`

  - `message: str`

  - `success: bool`

### Example

```python
import os
from linq import LinqAPIV3

client = LinqAPIV3(
    api_key=os.environ.get("LINQ_API_V3_API_KEY"),  # This is the default and can be omitted
)
stop_chat_location_sharing_response = client.chats.location.stop(
    chat_id="975d0776-bd17-4273-8337-f346b4c661b0",
    handle="+15551234567",
)
print(stop_chat_location_sharing_response.message)
```

#### Response

```json
{
  "success": true,
  "message": "Location sharing stop requested"
}
```

## Domain Types

### Get Chat Location Response

- `class GetChatLocationResponse: …`

  - `data: Data`

    - `features: List[DataFeature]`

      - `geometry: DataFeatureGeometry`

        - `coordinates: List[float]`

          [longitude, latitude]

        - `type: Literal["Point"]`

          - `"Point"`

      - `properties: DataFeatureProperties`

        - `handle: str`

          Phone number or email of the person sharing their location

        - `address: Optional[str]`

          Full street address

        - `locality: Optional[str]`

          City or locality name

        - `updated_at: Optional[datetime]`

          When the location was last updated

      - `type: Literal["Feature"]`

        - `"Feature"`

    - `type: Literal["FeatureCollection"]`

      - `"FeatureCollection"`

  - `success: bool`

### Location Request Response

- `class LocationRequestResponse: …`

  - `message: str`

  - `success: bool`

### Stop Chat Location Sharing Response

- `class StopChatLocationSharingResponse: …`

  - `message: str`

  - `success: bool`
