Import Locations Excel (Account – update existing)

Overview

Upload an Excel file (first sheet only) to update existing locations belonging to the authenticated account. Each row is matched by location_id against the location's saucode, then the store name/storeid and the location-account company's name/address/city/zip are written. Returns a success message plus a list of per-row errors that were skipped (state/city/store not found in the account).

Prerequisites

  • A bearer token. Callable with Account tokens.

Base URL

EnvironmentURL
Productionhttps://production-api.shoutaboutus.com
Developmenthttps://development-api.shoutaboutus.com

Endpoint

POST /api/v1/store/import-locations-excel

Authentication

  • Requires a bearer token in the Authorization: Bearer <bearer-token> header.

  • Who can call it: Account tokens.

  • Route is inside the authenticated group.

  • Requires the user's company bundle_id === 3 (ACCOUNT). A non-account user gets 403.

  • Scope is the caller's own account. Each matched store is INNER-joined store, then company (location-account), then company brand. The join is filtered to brand.bundle_id = 3, brand.deleted_at IS NULL, and brand.id = <auth user's company id>.

Rate limit

  • No rate limit.

Request body

  • Body (multipart/form-data):
FieldTypeRequiredDescription
excel_filefile (xlsx/xls)Yesmimetypes:application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, max:101376 KB (~99 MB). First worksheet only.

Per-row columns validated inside the controller (each row of the sheet): location_id (required, must be a known location), country_code (required, must be a known country code), state_code (required string), city_name (required string), zip_code (required), store_name (required string). Optional row columns also read: store_id, address. Any row-level validation failure returns a 400 with the full list of messages and processes nothing.

Response

  • data.status (string) — "success".
  • data.message (string) — "File has been uploaded.".
  • data.errors (array) — per-row skip messages (e.g. "Row #N - State code not found", "Row #N - City name not found", "Row #N - Location not found in your brand"). Empty when all rows applied.

200 OK · 200

{
  "data": {
    "status": "success",
    "message": "File has been uploaded.",
    "errors": [
      "Row #3 - City name not found",
      "Row #7 - Location not found in your brand"
    ]
  }
}

400 Empty / Invalid Rows · 400

{
  "message": "Bad Request",
  "status": "error",
  "errors": [
    "Row #2: ABC-999 - Location ID not found",
    "Row #4: XX - Country code not found"
  ]
}

422 Validation Error · 422

{
  "message": "The excel file field is required.",
  "errors": {
    "excel_file": [
      "The excel file field is required."
    ]
  }
}

Errors

StatusMeaning
400Empty / Invalid Rows
401The bearer token is missing, expired or invalid
403The token is valid but the record sits outside your account
422Validation Error
500Unexpected server error

Example request

curl --request POST \
  --url "https://production-api.shoutaboutus.com/api/v1/store/import-locations-excel" \
  --header 'Authorization: Bearer <bearer-token>' \
  --header 'Accept: application/json' \
  --form 'excel_file=@excel_file.xlsx'

Did this page help you?