TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/No-Country-simulation/G9-LATAM-Team-58/llms.txt
Use this file to discover all available pages before exploring further.
POST /contents/batch endpoint accepts a CSV file and ingests each data row as an independent content item, running the full ingestion pipeline — inference, embedding storage, and related-item search — for every row in sequence. Rows that fail (due to blank fields, malformed CSV, or inference errors) are recorded individually and do not abort the rest of the batch. This makes the endpoint resilient to partial data quality issues, but it also means you must inspect the failed count and errors array in the response to determine whether the upload was fully successful; the HTTP status code alone is not sufficient.
Endpoint
Request
A
.csv file to upload as a multipart/form-data field named exactly file. The file must not be empty, must have a .csv extension, and must not exceed 5 MB. The maximum total request size is 10 MB.CSV format
The file must have exactly two columns —title and body — in that order. The first row is always discarded (treated as a header), regardless of its content.
- Header row: The first line is unconditionally discarded. If your file has no header, the first data row is silently lost.
- Two columns only:
titleandbody. Fields likecategory,source, andurlcannot be set via batch upload. The category is predicted by the model;sourceis fixed to"user"andlanguageto"es"for every row, matching the behavior ofPOST /content. - Double-quote escaping: Commas within field values are supported if the field is wrapped in double quotes.
- No multi-line field support: A
bodyvalue that spans multiple lines within double quotes will be split across rows, producing invalid records. - Row numbering: Error row numbers start at
1after the header. The second line of the file isrow: 1, the third line isrow: 2, and so on.
Example request
Pre-processing validation
The following checks run before any row is processed. A failure here returns an error immediately with no rows ingested.| Condition | Response |
|---|---|
file field is empty | 400 VALIDATION_ERROR — "El archivo no puede estar vacío" |
Filename does not end in .csv | 400 VALIDATION_ERROR — "El archivo debe ser un CSV" |
| File exceeds 5 MB (or request exceeds 10 MB) | 400 VALIDATION_ERROR — "El archivo excede el tamaño máximo permitido" |
| Database not configured | 503 INTERNAL_ERROR — "Base de datos no configurada. Use app.database.enabled=true" |
.csv extension check is based on the filename only, not the file’s actual content. A renamed Excel file will pass this check and then generate per-row errors.
Response — 200 OK
The number of rows successfully ingested. Equals
ids.length.The number of rows that could not be ingested. Equals
errors.length. A value greater than 0 does not prevent the remaining rows from being processed.Array of IDs assigned to the successfully ingested items, in processing order. Each ID has the format
usr-<UUID>.Array of per-row error objects for rows that failed. Row numbers start at
1 after the header row.A map of category name to the count of successfully processed rows assigned to that category (e.g.
{"Backend": 3, "Bases de datos": 1}). Only categories that appear in at least one successfully processed row are included; categories with zero rows are omitted entirely.The
byCategory map reflects only successfully ingested rows. Failed rows do not contribute to any category count.Example response
Error responses
Errors that occur during pre-processing validation (before any row is ingested) return a standardApiError envelope and a non-200 status code. Every error response contains three fields:
| Field | Type | Description |
|---|---|---|
error | string | Machine-readable error code (e.g. VALIDATION_ERROR, INTERNAL_ERROR). |
message | string | Human-readable description of what went wrong, in Spanish. |
timestamp | string | ISO 8601 UTC timestamp of when the error was generated (e.g. "2026-07-28T10:32:41.123456Z"). |
| HTTP Status | error code | When it occurs |
|---|---|---|
400 Bad Request | VALIDATION_ERROR | File is empty, filename is not .csv, or the file or request exceeds the size limit. |
503 Service Unavailable | INTERNAL_ERROR | Database is not configured. Start the API with app.database.enabled=true. |
Example error — 400 Validation Error (empty file)
Example error — 400 Validation Error (size exceeded)
Transaction behavior and partial batches
Because each row runs the full ingestion pipeline —POST /predict to the inference service, INSERT, UPDATE of the embedding, and a SELECT vector-distance query for related items — large files involve a proportional number of network and database round-trips. The related items calculated during batch processing are computed internally and discarded; they do not appear in the BatchUploadResponse.
Recommendations for large uploads:
- Keep batches to approximately 50 rows to stay well within timeout limits. The hard limit is 5 MB, but processing time is the practical bottleneck.
- Save the
idsarray from every successful response. It is the only way to identify and clean up a partial upload, since there is no batch-level rollback. - Inform users that the upload may take several minutes for larger files — there is no progress stream; the HTTP response arrives only after all rows have been processed.