API — Locations
Location CRUD, image management, and CSV bulk import. All endpoints require auth:api, auth_session, and audit middleware. Results are workspace-scoped.
Endpoints
GET /locations
List locations in the active workspace.
Query params: workspace_id, finder_id (optional filter by finder association)
Response 200: Array of location objects.
GET /locations/{id}
Get a single location by numeric ID.
Response 200: Location object with address fields, lat/lng, tags, custom fields, and image URLs.
POST /locations
Create a new location.
Body:
{
"title": "Downtown Store",
"address": "123 Main St",
"city": "Austin",
"state": "TX",
"country": "US",
"zip": "78701",
"lat": 30.2672,
"lng": -97.7431,
"phone": "+15125550123",
"email": "store@example.com",
"website": "https://example.com",
"workspace_id": 1
}Response 201: Created location.
PUT /locations/{id}
Update a location’s fields. Partial updates are supported.
Response 200: Updated location.
DELETE /locations/{id}
Delete a location.
Response 204
Image endpoints
POST /locations/{id}/image
Upload an image for a location. Accepts multipart/form-data.
Body: image (file field) — JPEG or PNG.
The image is uploaded to R2 at workspaces/{workspace_id}/locations/{id}/{uuid}.{ext} and served via CDN. The CDN URL is returned in the response and stored on the location record.
Response 200: { image_url: "https://cdn.locationfinders.com/..." }
DELETE /locations/{id}/image
Remove the location’s image. Deletes from R2 on a best-effort basis (failure is logged but does not fail the request).
Response 200: Location with image_url: null.
Bulk import
POST /locations/import
Bulk-create or update locations from a CSV payload. The CSV must include the required fields (title, address columns). Custom fields are matched by name.
Body: multipart/form-data with a file field containing the CSV.
Response 200: { created, updated, skipped, errors[] } summary.
⚠️ Warning: The import endpoint replaces existing locations by matching on an internal key. Rows without a match are created; rows with a match are updated. There is no dry-run mode — validate the CSV before submitting.
Related pages
- Data model: Location
- API — AI Location Imports — AI-assisted location creation
- Backend: Storage — image upload to R2