Bulk import

Instead of creating POIs one by one, upload a CSV file and Lanewise imports it in the background: up to 50,000 rows per file. You can upload from the Imports page of the dashboard or with the API.

CSV format

The first row is the header. Column names are case-insensitive, and columns can be in any order. Use a comma or a semicolon as delimiter, and UTF-8 encoding.

  • Name
    name
    Type
    required
    Description

    Name of the POI, up to 255 characters.

  • Name
    latitude
    Type
    required
    Description

    Latitude between -90 and 90, with a dot as decimal separator.

  • Name
    longitude
    Type
    required
    Description

    Longitude between -180 and 180, with a dot as decimal separator.

  • Name
    category
    Type
    optional
    Description

    Name of the category. Categories that don't exist yet are created.

  • Name
    any other column
    Type
    optional
    Description

    The value of the attribute with that name. The value must match the attribute type; leave the cell empty to skip it. Unknown columns are rejected, unless you send create_missing_attributes=1 to create them as text attributes.

lanewise-pois-sample.csv

name,latitude,longitude,category,owner_id
Mercat de la Boqueria,41.3818,2.1716,market,client_1042
Park Güell,41.4145,2.1527,park,client_2001
Depot Zona Franca,41.3440,2.1370,depot,client_1042

How imports run

  1. When you upload the file, Lanewise checks the header and counts the rows. A file with a missing required column, unknown columns, no rows or more than 50,000 rows is rejected right away with a 422.
  2. The import is queued and processed in batches of 500 rows. Rows that fail validation are skipped and reported with their line number; the rest are imported.
  3. Every imported POI is reverse-geocoded in the background, at about one POI per second, so addresses fill in gradually after the import finishes.

Imports respect your team's POI limit. When the limit is reached, the remaining rows are reported as not imported and limit_reached is true. The upload itself counts as one request towards your rate limit.


POST/v1/imports

Upload a CSV file

Send the file as multipart/form-data. Returns a 202 with the import, which you can poll for progress. Requires the create-pois permission.

Required attributes

  • Name
    file
    Type
    file
    Description

    The CSV file, up to 10 MB and 50,000 rows.

Optional attributes

  • Name
    create_missing_attributes
    Type
    boolean
    Description

    Create unknown columns as text attributes instead of rejecting the file. Defaults to false.

Request

POST
/v1/imports
curl https://api.lanewise.app/v1/imports \
  -H "X-API-KEY: {YOUR_API_KEY}" \
  -F [email protected] \
  -F create_missing_attributes=1

Response (202)

{
  "data": {
    "id": "01J9ZD1K7Q2W8TYB6M4C0HNX3E",
    "status": "queued",
    "filename": "lanewise-pois-sample.csv",
    "columns": ["name", "latitude", "longitude", "category", "owner_id"],
    "total_rows": 12,
    "processed_rows": 0,
    "created": 0,
    "failed": 0,
    "limit_reached": false,
    "errors": [],
    "created_at": "2026-09-27T09:30:00.000000Z",
    "started_at": null,
    "finished_at": null
  }
}

GET/v1/imports/:id

Check an import

Poll this endpoint until status is completed or failed. errors lists up to 100 rows that were not imported, with their line number in the file. See the import resource for every field.

Request

GET
/v1/imports/01J9ZD1K7Q2W8TYB6M4C0HNX3E
curl https://api.lanewise.app/v1/imports/01J9ZD1K7Q2W8TYB6M4C0HNX3E \
  -H "X-API-KEY: {YOUR_API_KEY}"

Response

{
  "data": {
    "id": "01J9ZD1K7Q2W8TYB6M4C0HNX3E",
    "status": "completed",
    "total_rows": 12,
    "processed_rows": 12,
    "created": 11,
    "failed": 1,
    "limit_reached": false,
    "errors": [
      { "line": 5, "message": "The latitude must be a number between -90 and 90." }
    ],
    // ...
  }
}