Import Locations (admin – create verified)

Overview

Admin "create verified" import: validates the same Excel file/header/rows, then for each row persists an RsImportLocation record (company_id = account_id, location_name, raw row_data JSON) and dispatches a CreateLocation job to actually create the location asynchronously.

Prerequisites

  • A bearer token. Callable with Partner and Account tokens.

Base URL

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

Endpoint

POST /api/v1/import/locations

Authentication

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

  • Who can call it: Partner and Account tokens.

  • In the top-level authenticated group.

  • The endpoint scopes the target by the account_id rule. It must be a company row with bundle_id=3 (Account), not soft-deleted, and pass an ownership check (a check that the record sits inside your own hierarchy).

  • A Partner (bundle_id=1) reaches Accounts under their tree.

  • An Account user reaches Accounts in their own hierarchy.

Rate limit

  • No rate limit.

Request body

  • Body (multipart/form-data):
FieldTypeRequiredDescription
account_idintegeryesMust be an existing, non-deleted account, and belong to the auth user's hierarchy (an ownership check). Used as company_id.
location_filefile (xlsx/xls)yesmimetypes:application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, max 10240 KB. Same 14-column header template as bulk-upload.

Per-row rules are identical to POST /api/v1/bulk-upload/locations: required address, city, state, zip, business_phone (9-10 digits), country_code (must be a known country code), location_name. Optional gbp_name, location_user_phone_number_optional, location_user_email_address_optional (valid/unique/distinct email); #NAME? formula values rejected.

Response

  • data.status (string) — The endpoint saves "success" once rows and jobs dispatched, "error" when per-row validation fails.
  • data.message (string) — human-readable status text.
  • data.errors (object, only when status=error) — map keyed by spreadsheet row number (data row index + 2) to arrays of error message strings.

200 OK · 200

{
  "data": {
    "status": "success",
    "message": "Thank you very much. File has been uploaded. Location creation is currently underway"
  }
}

200 Row Validation Errors · 200

{
  "data": {
    "message": "Please correct the errors and re-upload the file.",
    "status": "error",
    "errors": {
      "2": [
        "The location name field is required."
      ],
      "6": [
        "The User email already registered. Please enter a different email address"
      ]
    }
  }
}

200 Bad Header / Empty File · 200

{
  "message": "OK",
  "status": "error",
  "errors": "The Excel file is invalid. The header names and order must match those in the template file."
}

422 Validation Error · 422

{
  "message": "The account is invalid or deleted. (and 1 more error)",
  "errors": {
    "account_id": [
      "The account is invalid or deleted.",
      "The selected account id does not belong to your company hierarchy."
    ],
    "location_file": [
      "The location file field is required."
    ]
  }
}

Errors

StatusMeaning
401The bearer token is missing, expired or invalid
422Validation Error
500Unexpected server error

Example request

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

Did this page help you?