Skip to main content

Imports

The Imports API is our new in-house replacement for the Nuvo-style import flow. It is designed for structured tabular uploads where a client needs to:
  • upload a source file
  • map source columns to a Dcycle template
  • inspect distinct raw values for category fields
  • validate rows before ingestion
  • patch a subset of rows when validation fails
  • submit the cleaned dataset into downstream processing
This API is especially useful for automation, partner integrations, and eventually dcy.
The Imports API is a session-based workflow. You do not send one big “import everything” request. Instead, you create an import session, validate it, optionally correct rows, and only then submit it.

End-to-End Flow

1

1. Create session

Call POST /v2/imports/sessions with a template_id and the source file as multipart form data.The backend parses the file and returns:
  • import_id
  • detected source columns
  • sample rows
  • sheet/header metadata
2

2. Suggest mapping

Call POST /v2/imports/{import_id}/mapping/suggest.This returns a best-effort mapping suggestion from source columns to template columns. Clients can accept these suggestions as-is or adjust them before validation.
3

3. Inspect category values

Call POST /v2/imports/{import_id}/unique-values with the current mapping.The backend returns distinct raw values for mapped category columns only. This is the right moment to build a value-mapping UI before row-level validation starts.
4

4. Validate rows

Call POST /v2/imports/{import_id}/validate with the chosen mapping.The response includes:
  • valid_rows
  • error_rows
  • errors_by_column
  • paginated row-level validation output
5

5. Review rows

Call GET /v2/imports/{import_id}/rows to page through the processed rows.Use errors_only=true when you only want rows that still need action.
6

6. Patch corrections

If some rows are invalid, call PATCH /v2/imports/{import_id}/rows with row-level corrections.The backend revalidates the corrected rows and returns updated row data plus the remaining error count.
7

7. Submit import

Once the session is valid, call POST /v2/imports/{import_id}/submit.Submission creates the downstream processing artifact and starts the heavy processing pipeline.
8

8. Check status

Call GET /v2/imports/{import_id}/status to retrieve the session status and processing summary.
For most clients, the safest workflow is:
  1. Create the session.
  2. Request mapping suggestions.
  3. Inspect distinct values for mapped category columns.
  4. Validate with the chosen mapping.
  5. If there are errors, fetch or display only invalid rows.
  6. Patch corrections until the session is clean.
  7. Submit the import.
  8. Poll status until downstream processing has clearly started.

Typical Session Example

1. Create the session

curl -X POST "https://api.dcycle.io/v2/imports/sessions" \
  -H "x-api-key: ${DCYCLE_API_KEY}" \
  -H "x-organization-id: ${DCYCLE_ORG_ID}" \
  -F "template_id=logistics_requests" \
  -F "numeric_locale=es_ES" \
  -F "upload_file=@./logistics.csv;type=text/csv"
Example response:
{
  "import_id": "11111111-1111-1111-1111-111111111111",
  "file_name": "logistics.csv",
  "total_rows": 240,
  "numeric_locale": "es_ES",
  "sheets": [],
  "selected_sheet": null,
  "detected_header_row": 0,
  "source_columns": [
    "Trip Date",
    "Client",
    "Distance",
    "Origin Country",
    "Destination Country"
  ],
  "sample_rows": [
    ["2026-03-01", "ACME", "125,4", "ES", "FR"]
  ]
}

2. Ask for mapping suggestions

curl -X POST "https://api.dcycle.io/v2/imports/11111111-1111-1111-1111-111111111111/mapping/suggest" \
  -H "x-api-key: ${DCYCLE_API_KEY}" \
  -H "x-organization-id: ${DCYCLE_ORG_ID}" \
  -H "Content-Type: application/json" \
  -d '{}'

3. Validate using a chosen mapping

{
  "mapping": {
    "trip_date": "Trip Date",
    "client": "Client",
    "distance_km": "Distance",
    "origin_country": "Origin Country",
    "destination_country": "Destination Country"
  }
}
curl -X POST "https://api.dcycle.io/v2/imports/11111111-1111-1111-1111-111111111111/validate?page=1&page_size=50" \
  -H "x-api-key: ${DCYCLE_API_KEY}" \
  -H "x-organization-id: ${DCYCLE_ORG_ID}" \
  -H "Content-Type: application/json" \
  -d @mapping.json

4. Inspect distinct category values

curl -X POST "https://api.dcycle.io/v2/imports/11111111-1111-1111-1111-111111111111/unique-values" \
  -H "x-api-key: ${DCYCLE_API_KEY}" \
  -H "x-organization-id: ${DCYCLE_ORG_ID}" \
  -H "Content-Type: application/json" \
  -d @mapping.json

5. Patch one bad row

{
  "corrections": [
    {
      "row_index": 17,
      "column": "distance_km",
      "value": 128.4
    }
  ]
}

6. Submit the import

curl -X POST "https://api.dcycle.io/v2/imports/11111111-1111-1111-1111-111111111111/submit" \
  -H "x-api-key: ${DCYCLE_API_KEY}" \
  -H "x-organization-id: ${DCYCLE_ORG_ID}" \
  -H "x-partner: dcycle" \
  -H "Content-Type: application/json" \
  -d '{"ignore_errors": false}'
Example response:
{
  "status": "processing",
  "file_id": "22222222-2222-2222-2222-222222222222",
  "processing_job_id": "33333333-3333-3333-3333-333333333333",
  "rows_submitted": 240
}

Template Metadata

Use GET /v2/imports/templates/{template_id} to retrieve the target template definition before or during mapping. This is helpful when clients need to:
  • render a column picker
  • show required vs optional target fields
  • display allowed category options
  • apply defaults from the backend template definition
When a category column uses options_source instead of inline options, call GET /v2/imports/options/{source_key} to fetch the resolved list of selectable values and labels from the backend registry. When a client needs to inspect the raw values present in the uploaded file before validation, call POST /v2/imports/{import_id}/unique-values with the chosen mapping. Typical examples:
  • countries for country fields
  • logistics_tocs for logistics vehicle types
  • fuels for logistics recharge fuel selection

Status Lifecycle

created -> parsed -> mapped -> validating -> validated -> submitting -> submitted
                     |
                     +-> failed
In practice, clients will most commonly observe:
  • created briefly at session creation time before parsing metadata is persisted
  • parsed after session creation
  • validated after a successful validation pass
  • submitted after the import has been handed off for downstream processing

Best Practices

  • Persist the import_id on the client side so users can safely resume a session.
  • Use errors_only=true when rendering review tables for large imports.
  • Use the unique-values endpoint before validation if your client supports category value mapping.
  • Treat mapping suggestions as hints, not guaranteed matches.
  • Do not submit until validation is clean unless you intentionally support ignore_errors=true.
  • Use the template metadata endpoint to avoid hardcoding target columns in the client.