---
title: "Submit Import Job For New Project"
method: POST
path: "/api/v1/project/sandbox/from-upload"
tags: ["project"]
---

# Submit Import Job For New Project

`POST /api/v1/project/sandbox/from-upload`

Start a background import as a NEW project (Door 1, async).

Returns as soon as the project row and the job exist, so the client can
navigate straight to a project that reads as not-yet-ready while the import
runs. The county is the caller's, picked on the map as on Address Search, so
the request path reads no sandbox.

Separate from ``/sandbox/from-features`` rather than a branch inside it: that
route's ``upload`` field means "here are the matches I already resolved", and
quietly re-pointing it at background execution would strand a browser tab
open across the deploy.

## Headers

- `Idempotency-Key` string, nullable

## Request body

- ImportSubmitNewProjectRequest — Start a background import into a new project in the caller's county. County-first like Address Search: the person picks the county on the map, and every row is matched inside it.
  - `upload` ImportUploadSubmit, required — The held-upload half of an ASYNC submit — no matches, by construction. The synchronous twin (``ImportUploadCommit``) carries the client's resolved matches because the browser did the resolving. Here the job resolves, so the client sends only which columns compose each row's address query and which to carry through; a ``matches`` field would be a second, stale source for something the server is about to derive.
    - `token` string, required
    - `address_columns` string[], required
    - `mapped_columns` string[]
  - `spine` 'matched_only' | 'all_rows'
  - `knowledge_skill_workspace_id` string, uuid, nullable
  - `layer_name` string, nullable — Name for the matched-features layer. In-project route only — the new-project route names its layers from the create flow. Blank or absent falls back to a name derived from the matched feature ids.
  - `county_fips` string, required

## Response `200`

Successful Response

- ImportSubmitResponse — What a submit returns once the job is durably enqueued. The project id is present for both doors — Door 1 creates the project during the submit so the client can navigate to it immediately, reading as not-yet-ready until the job finishes. ``county_fips`` is what that immediate navigation frames the map against: the project has no features until the job commits, so its county extent is the only camera the view can take. Door 1 echoes the caller's county; Door 2 echoes the project's own.
  - `project_id` string, uuid, required
  - `import_job_id` string, uuid, required
  - `county_fips` string, required

## Other responses

- `422` — Validation Error

## Changes

- **2026-09-25** `bb508e935174` — 1 breaking
  - added the new required request property `county_fips`
- **2026-08-31** `4c1b045ef2af` — 1 info
  - added the new optional `header` request parameter `Idempotency-Key`
- **2026-08-08** `ba2b8d962161` — 1 info
  - added the new optional request property `knowledge_skill_workspace_id`

[Change history](https://skmtc.dev/maia-analytics/apis/maia-api/changes/api/v1/project/sandbox/from-upload/post.md)

---

[API](https://skmtc.dev/maia-analytics/apis/maia-api.md) · [All operations](https://skmtc.dev/maia-analytics/apis/maia-api/llms.txt) · [OpenAPI document](https://skmtc.dev/maia-analytics/apis/maia-api/revisions/bb508e935174?raw)
