Custom endpoints let you offer pickup points from any source not covered by our built-in carrier integrations. This feature requires Shopify Plus and a developer to implement the endpoint.
#How it works
In Shopify Admin → Atlas Pickup Points, open the pickup point configuration, select Custom as the carrier, and paste your endpoint URL. Each time pickup points are displayed, Atlas makes a GET request to your endpoint with the following query parameters:
| Parameter | Name | Description |
|---|---|---|
| lat | Latitude | Latitude of the buyer’s shipping address or their position on the map |
| lng | Longitude | Longitude of the buyer’s shipping address or their position on the map |
| country_code | Country code | Country code (ISO 3166-1 alpha-2) of the buyer’s shipping address. Does not change if the buyer moves the map to a different country. |
| q | Search query | Optional: search query from the list view. Search can be enabled in the custom endpoint settings. |
If your endpoint requires additional options, you can pass them as query parameters and they will be merged with the parameters above.
#Authentication
If your endpoint requires authentication, you can add a secret in the custom endpoint settings. Atlas will send it as the x-atlas-pickup-points-secret header with every request, allowing your endpoint to verify that the request is coming from Atlas.
The endpoint URL must serve the response directly. Redirects (3xx responses) are not followed, so it must point to the final location.
Your endpoint must respond with JSON in the following format:
{
"locations": [
{
"code": "019889",
"address": {
"address1": "19 BOULEVARD GALLIENI",
"address2": null,
"city": "NEUILLY PLAISANCE",
"zip": "93360",
"country_code": "FR",
"latitude": 48.8532417,
"longitude": 2.514444
},
"details": {
"name": "NEW HIGH TECH GSM",
"description": null,
"business_hours": [
{
"day": "MONDAY",
"opening_time": "08:00",
"closing_time": "21:00"
},
{
"day": "TUESDAY",
"opening_time": "08:00",
"closing_time": "21:00"
},
{
"day": "WEDNESDAY",
"opening_time": "08:00",
"closing_time": "21:00"
},
{
"day": "THURSDAY",
"opening_time": "08:00",
"closing_time": "21:00"
},
{
"day": "FRIDAY",
"opening_time": "08:00",
"closing_time": "21:00"
},
{
"day": "SATURDAY",
"opening_time": "08:00",
"closing_time": "21:00"
},
{
"day": "SUNDAY",
"opening_time": "09:00",
"closing_time": "20:00"
}
],
"open_24_hours": false
},
"attributes": [
{
"key": "type",
"value": "PUDO"
}
]
},
{
"code": "014514",
"address": {
"address1": "32 RUE ROGER-SALENGRO",
"address2": null,
"city": "FONTENAY SOUS BOIS",
"zip": "94120",
"country_code": "FR",
"latitude": 48.855606,
"longitude": 2.474787
},
"details": {
"name": "LOCKER 24/7 INTERMARCH ROGER SA",
"description": null,
"business_hours": [],
"open_24_hours": true
},
"attributes": [
{
"key": "type",
"value": "LOCKER"
}
]
}
]
}
#Response
#Response object
| Key | Required | Type | Description |
|---|---|---|---|
| locations | true | Location[] | List of available pickup points for the requested coordinates |
| error_message | false | String | Error message visible in the network response (not shown in the UI) |
#Location object
| Key | Required | Type | Description |
|---|---|---|---|
| code | true | String | Unique identifier of the pickup point |
| address | true | Address | Pickup point address |
| details | true | Details | Pickup point details |
| attributes | false | Attributes[] | Additional attributes that will be passed to the order |
| icon_url | false | String | URL of the map pin icon. Should be a PNG hosted on Shopify CDN. |
#Address object
| Key | Required | Type | Description |
|---|---|---|---|
| address1 | true | String | First line of the address (street and number) |
| address2 | false | String | Second line of the address (not visible to the buyer) |
| city | true | String | City |
| zip | true | String | Postal code |
| country_code | true | String | Country code ISO 3166-1 alpha-2 |
| latitude | true | Float | Latitude |
| longitude | true | Float | Longitude |
#Details object
| Key | Required | Type | Description |
|---|---|---|---|
| name | true | String | Location name, displayed to the buyer |
| description | false | String | Description of the location, displayed to the buyer |
| business_hours | false | BusinessHour[] | List of opening hours. If unknown or 24/7, send empty array. |
| open_24_hours | false | Boolean | Is the location open 24/7? If unknown, send false. |
#BusinessHour object
| Key | Required | Type | Description |
|---|---|---|---|
| day | true | Enum: MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY SUNDAY | Day of the week |
| opening_time | true | String | Time in 24h format, for example: 01 or 23 |
| closing_time | true | String | Time in 24h format, for example: 01 or 23 |
#Attributes object
| Key | Required | Type | Description |
|---|---|---|---|
| key | true | String | Key of the attribute |
| value | true | String / Boolean / Number | Value of the attribute |
#TypeScript type
type CustomIntegrationResponse = {
error_message?: string | null;
locations: {
code: string;
address: {
address1: string;
address2?: string | null;
city: string;
zip: string;
longitude: number;
latitude: number;
country_code: string;
};
details: {
name: string;
description?: string | null;
business_hours: {
day: "MONDAY" | "TUESDAY" | "WEDNESDAY" | "THURSDAY" | "FRIDAY" | "SATURDAY" | "SUNDAY";
opening_time: string;
closing_time: string;
}[];
open_24_hours: boolean;
};
attributes: {
key: string;
value: string | number | boolean;
}[];
icon_url?: string | null;
}[];
};
#Implementation tips
#Hosting options
We recommend Heroku, AWS Lambda, or Cloudflare Workers. For the best performance and lowest latency, deploy in the EU region, preferably AWS eu-west-1 (Ireland), where our infrastructure is located.
For static locations (up to 50):
- Create a JSON file with your locations
- Upload it in Shopify Admin → Content → Files
- Use the CDN URL as your endpoint
#Troubleshooting
If you receive a CUSTOM_INTEGRATION_INVALID_RESPONSE error:
- Open your browser’s Developer Tools
- Go to the Network tab
- Find the request to the
/locationsendpoint - Inspect the response to see detailed error information
While we don’t assist with implementation, our support team is happy to help with debugging issues.