Skip to main content

Developer reference

Custom endpoint

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:00 or 23:49
closing_time true String Time in 24h format, for example: 01:00 or 23:49

#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):

  1. Create a JSON file with your locations
  2. Upload it in Shopify Admin → Content → Files
  3. Use the CDN URL as your endpoint

#Troubleshooting

If you receive a CUSTOM_INTEGRATION_INVALID_RESPONSE error:

  1. Open your browser’s Developer Tools
  2. Go to the Network tab
  3. Find the request to the /locations endpoint
  4. 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.