Import entities (CSV)
curl --request POST \
--url http://api.gu1.ai/batch-import/import/entities \
--header 'Authorization: Bearer <token>'import requests
url = "http://api.gu1.ai/batch-import/import/entities"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('http://api.gu1.ai/batch-import/import/entities', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "http://api.gu1.ai/batch-import/import/entities",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "http://api.gu1.ai/batch-import/import/entities"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://api.gu1.ai/batch-import/import/entities")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("http://api.gu1.ai/batch-import/import/entities")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_bodyAPI Reference
Import entities (CSV)
Upload a CSV and enqueue bulk entity import β platform format without mappingId or custom columns with mappingId. Manual by default; automatic when explicit.
POST
/
batch-import
/
import
/
entities
Import entities (CSV)
curl --request POST \
--url http://api.gu1.ai/batch-import/import/entities \
--header 'Authorization: Bearer <token>'import requests
url = "http://api.gu1.ai/batch-import/import/entities"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('http://api.gu1.ai/batch-import/import/entities', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "http://api.gu1.ai/batch-import/import/entities",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "http://api.gu1.ai/batch-import/import/entities"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://api.gu1.ai/batch-import/import/entities")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("http://api.gu1.ai/batch-import/import/entities")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_bodyEndpoint
POST https://api.gu1.ai/batch-import/import/entities
Overview
Content-Type:multipart/form-data.
Enqueues the same bulk job as the dashboard Bulk imports hub. Requires entities:bulk_import and org bulk automatic entity import enabled. 202 response includes jobId and effective importMode.
Authentication
Authorization: Bearer YOUR_API_KEY
Import Modes (entityImportMode)
| Mode | When | Behavior |
|---|---|---|
manual | Default when the field is omitted | Minimal entity from taxId + suggested_name (required). No country basic-data pipeline (Nosis/CPF). Optional selected enrichments via form autoExecuteIntegrations and/or per-row CSV columns. No shareholder depth. Country: any valid platform ISO2 (country_code per row takes priority). If optional enrichments fail, the entity is still created. |
automatic | Send entityImportMode=automatic | Same pipeline as Create entity automatically: basic data by tax ID (AR, BR, or CL) + extra enrichments (defaults to all active when autoExecuteIntegrations omitted) + optional depth / shareholders. If basic data fails, the entity is not kept. |
Legacy values
manual_no_enrichment and automatic_enriched are still accepted on input and normalized to manual / automatic. Responses use the canonical names.If an enrichment fails (per row)
Each CSV row is processed independently. Default: a failed row is recorded and the job continues with the next row. SetstopOnFirstError=true to stop after the first failure (rows already created stay).
manual | automatic | |
|---|---|---|
| Same as | Dashboard Manual create | POST /entities/automatic |
| Blocking step | Insert with taxId + suggested_name | Basic-data enrichment for that country and type |
| Argentina basic data | Not used | Nosis when it is active in the marketplace; otherwise the catalog fallback (typically ar_arca_contribuyente_enrichment) |
| Basic data / create fails | Entity is not created; row failed | Stub is discarded; entity is not kept; row failed |
| Extra enrichments fail (e.g. BCRA after a successful basic-data step) | Entity stays; failure is on enrichment history | Entity stays; failure is on enrichment history (partial_success on the create). Does not roll back the row. |
automatic, extra enrichments (Argentina BCRA, etc.) run only after basic data succeeds. A BCRA error never aborts a create whose basic-data step already succeeded.
Default When Sending Only the CSV
curl -X POST 'https://api.gu1.ai/batch-import/import/entities' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-F 'file=@bulk-entities-template.csv'
importMode: manual β minimal entity, no enrichments unless you add them explicitly.
Manual with Selected Enrichments
Same semantics as the dashboard Manual mode:curl -X POST 'https://api.gu1.ai/batch-import/import/entities' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-F 'file=@bulk-entities-template.csv' \
-F 'entityImportMode=manual' \
-F 'autoExecuteIntegrations={"executeAllActiveEnrichments":false,"enrichments":["nosis_enrichment"]}' \
-F 'riskMatrixCompanyId=YOUR_MATRIX_UUID'
monitoring JSON (main entity only in manual mode).
Automatic Mode (Explicit)
curl -X POST 'https://api.gu1.ai/batch-import/import/entities' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-F 'file=@bulk-entities-template.csv' \
-F 'entityImportMode=automatic'
autoExecuteIntegrations in automatic mode β all active enrichments for the org.
With depth > 0, send autoExecuteIntegrationsShareholders (JSON) for shareholders.
Manual without Post-Create Rules
-F 'entityImportMode=manual' \
-F 'skipRulesExecution=true'
entityImportMode β manual is already the default.)
Risk-matrix action after completion
The optional multipart fieldpostImportActions accepts a JSON array. The run_risk_matrix_filtered action queues a bulk risk-matrix execution after the job reaches completed:
-F 'postImportActions=[{"type":"run_risk_matrix_filtered","filters":{"type":"company"},"riskMatrixCompanyId":"YOUR_MATRIX_UUID","relatedEntitiesOfCreatedEntitiesOnly":true}]'
relatedEntitiesOfCreatedEntitiesOnly=true, Gu1 evaluates only entities directly linked βas source or targetβ to rows whose outcome in this file was created. filters.type determines whether related entities must be company or person, and the matching matrix is required. Rows with skipped_existing or failed are excluded. Without this flag, filters applies to the organizationβs full entity list.
Alternatively, send sourceImportJobId with the ID of a previous completed entity import. Gu1 runs the matrix only on that batchβs created rows matching filters.type, including entities not linked to rows in the current file. sourceImportJobId and relatedEntitiesOfCreatedEntitiesOnly=true are mutually exclusive. The previous import must belong to the same organization and have its full report available.
You can also send onlyWithoutRiskMatrixExecution=true to evaluate every entity of filters.type that does not yet have a matrix-execution audit. Once an entity is processed successfully, later imports do not include it again. The three scopes (sourceImportJobId, related entities, and no previous execution) are mutually exclusive.
Platform CSV (no mappingId)
Minimum headers: tax_id, type. Recommended: suggested_name (required in manual mode). See Country (ISO2) below for country_code.
Country (ISO2) β Always Required
Every entity row needs a country to create the record (manual and automatic). Provide it in one or both places:| Source | When to use |
|---|---|
Batch form field country | Step 2 in the hub, or multipart field in the API. Required for simple CSV (only tax_id + type). Required for any row that omits country_code. |
CSV column country_code (alias country) | Per row. Overrides batch country when present. |
country_code on the row β batch country.
If neither is set for a row, the import fails with missing country before the job runs.
| Mode | Allowed countries |
|---|---|
Automatic (automatic) | AR, BR, CL (basic-data pipeline) |
Manual (manual) | Any valid platform ISO2 |
- Simple CSV, all rows Argentina β headers
tax_id,type+ formcountry=AR. - Advanced CSV, mixed countries β include
country_codeon each row (formcountryoptional fallback). - Advanced CSV, single country β either all rows with
country_code=ARor formcountry=ARwithout the column.
- bulk-entities-template-automatic.csv β use with
entityImportMode=automatic. AR/BR/CL demo rows,depth,create_relationships,execute_all_active_enrichments. - bulk-entities-template-manual.csv β use with
entityImportMode=manual(default). AR/MX/BR demo rows,suggested_namefilled, nodepthcolumns (any ISO2).
apps/web/src/lib/bulk-automatic-entity-import-parse.ts.
Automatic example (truncated):
tax_id,type,country_code,suggested_name,...,execute_all_active_enrichments,...,depth,status,segment_tag
20123456789,company,AR,Acme Argentina SA,...,true,...,0,under_review,retail
12345678000190,company,BR,Loja Brasil Ltda,...,true,...,1,under_review,wholesale
tax_id,type,country_code,suggested_name,...,status,segment_tag
20123456789,company,AR,Empresa Manual AR SA,...,under_review,retail
XAXX010101000,company,MX,Empresa MΓ©xico Demo SA,...,active,latam
bulk-entities-template.csv is no longer used by the hub; pick the template matching your entityImportMode.
Column Reference (Platform CSV)
Header names are case-insensitive; spaces become_ (e.g. country code β country_code). Aliases in parentheses.
| CSV column | Aliases | API / entity field | Notes |
|---|---|---|---|
tax_id | taxId | taxId | Required. Normalized per country (e.g. CUIT formatting for AR). |
type | tipo | type | Required. person / company (also persona, empresa, pf, pj). |
country_code | country | country | ISO2 per row. Overrides batch form country. Column is optional in the CSV when batch country is sent (simple CSV) or when every row includes country_code. Country is always required β row column and/or batch field. |
suggested_name | name, nombre | suggestedName | Display name. Required in manual mode on every row. Recommended in automatic. |
gender | β | gender | Passed to entity creation (customData). Enum: M, F, male, female, other, unknown. Use other for non-binary. See Create entity β Person. |
external_id | externalId | externalId | External reference on the entity. |
email | β | email | Contact email on the entity. |
phone | β | phone | Contact phone on the entity. |
registration_date | β | registrationDate | Registration date (ISO string). |
risk_matrix_id | β | riskMatrixId | UUID of a risk matrix for this row, or empty / null to clear. Invalid values are skipped. Overrides batch riskMatrixPersonId / riskMatrixCompanyId when set. |
execute_all_active_enrichments | β | autoExecuteIntegrations.executeAllActiveEnrichments | true / false / 1 / 0. Row-level enrichments apply when this column, enrichments, or enrichment_group_refs is present. |
enrichments | β | autoExecuteIntegrations.enrichments | Comma- or semicolon-separated marketplace provider codes. Merged with batch form autoExecuteIntegrations when the row sets enrichment columns. |
enrichment_group_refs | β | autoExecuteIntegrations.enrichmentGroupRefs | Comma-separated enrichment group slugs from the marketplace. |
omit_enrichments | exclude_enrichments | autoExecuteIntegrations.excludeEnrichments | Provider codes to omit from the final resolved set. Works with execute_all_active_enrichments=true (all active minus these). When this is the only enrichment column on the row, it merges onto the batch config instead of replacing it. |
create_relationships | β | createRelationships | true / false. Automatic mode only (ignored in manual). |
depth | β | depth | Integer 0β5. Shareholder/relationship expansion. Automatic mode only (stripped in manual). Batch form depth applies when the row omits this column. |
related_tax_id | β | relationships[].relatedTaxId | Existing counterpart by tax ID. Exactly one of related_tax_id / related_external_id / related_entity_id per row. |
related_external_id | β | relationships[].relatedExternalId | Counterpart by externalId. |
related_entity_id | β | relationships[].relatedEntityId | Counterpart by UUID. |
relationship_type | β | relationships[].relationshipType | Defaults to shareholder when a counterpart is set. Graph enum. |
relationship_role | β | relationships[].role | Role in metadata.roles (e.g. SOCIO). |
relationship_as_source | β | relationships[].asSource | Default true: the created row is source and the counterpart (related_*) is target. With relationship_type=shareholder, the row is a shareholder of that counterpart. false reverses the direction. |
status | β | status | One of: active, inactive, blocked, under_review, pending_verification, awaiting_information, suspended, expired, deleted, rejected, not_started. |
attributes.<path> | β | attributes | Nested business data (same dot notation as native transaction CSV). E.g. attributes.segment_tag, attributes.tags.tier. |
entityData.<path> | β | entityData.{person|company} | KYC/KYB profile fields. Without person/company in the header, the row type selects the bucket (person β entityData.person.*, company β entityData.company.*). E.g. entityData.income, entityData.tradeName. |
entityData.person.<path> | β | entityData.person | Explicit person path. |
entityData.company.<path> | β | entityData.company | Explicit company path. |
metadata.<path> | β | attributes (legacy) | Deprecated; merged into attributes. Prefer attributes.*. |
| Unprefixed column | β | attributes | Backward compatible: segment_tag β attributes.segment_tag. |
Same entity, multiple links (CSV): platform CSV supports one relationship per row. If the same person/company appears on several rows with different
related_*, Gu1 does not recreate the entity (duplicate tax_id skip) but still applies that rowβs link. If the edge (source β target + type) already exists, that link is skipped (idempotent). API/JSON alternative: a single create with up to 10 items in relationships[].Removed (2026-06-04): CSV columns
execute_all_active_checks and checks are no longer part of the import contract. Use enrichments, enrichment_group_refs, and execute_all_active_enrichments instead. See Changelog.entityData; CSV values are re-applied at the end (CSV wins on conflicts).
What goes to attributes: attributes.*, legacy metadata.*, or unprefixed columns. Batch-level form field attributes (JSON) is merged with per-row attributes (row wins on key collision).
Simple CSV (only tax_id + type): send batch form field country (ISO2) β required. No country_code column needed.
Custom CSV (non-platform headers): use a saved mappingId β column mapping is defined in the dashboard, not by this table.
- Per-row enrichment columns apply in both modes when set on the row;
depth/ shareholders only inautomatic.
Related-Entity Enrichments per Row (Platform CSV)
Optional βautomatic mode only. Prefix relationship_ (plural alias relationships_).
| Column | Description |
|---|---|
relationship_execute_all_active_enrichments | true = all active enrichments on shareholders/related entities; false = basic data only. Replaces the batch policy (childEnrichmentPolicy) for that row. |
relationship_enrichments_company | Provider codes for company-type children (comma or semicolon separated) |
relationship_enrichments_person | Provider codes for person-type children |
relationship_enrichment_group_refs | Marketplace groups (optional) |
relationship_omit_enrichments | Alias of relationship_exclude_enrichments. Codes to omit from the final set (also with execute_all_active=true). When this is the only relationship_* column on the row, it merges onto the batch policy instead of replacing it. |
relationship_exclude_enrichments | Same as relationship_omit_enrichments (legacy name). |
relationship_execute_all_active_enrichments from the CSV if you want step-2 form policy to apply. Use relationship_omit_enrichments per row for one-off exceptions only.
Example: batch all-active on shareholders except global sanctions on children:
tax_id,type,country_code,depth,relationship_omit_enrichments
67250861000107,company,BR,1,global_gueno_sanctions_enrichment
Custom CSV
Non-platform column layout βmappingId required (entity_person / entity_company / entity_mixed mapping).
Form Fields
| Field | Required | Description |
|---|---|---|
file | Yes | CSV file |
mappingId | Conditional | Custom columns. Optional for platform format. |
entityImportMode | No | manual (default) or automatic |
country | Conditional (required in practice) | Batch ISO2. Required when CSV has no country_code on a row (typical simple CSV). Optional fallback when every row includes country_code. |
riskMatrixPersonId | No | UUID β both modes |
riskMatrixCompanyId | No | UUID β both modes |
skipRulesExecution | No | true / false (default false) |
stopOnFirstError | No | true / false. Default false: process every row; failures go to the job report. true: stop after the first failed row; earlier creates are kept. |
autoExecuteIntegrations | No | JSON β manual: optional selected enrichments; automatic: defaults to all active when omitted |
autoExecuteIntegrationsShareholders | No | JSON at batch level β automatic mode only + depth > 0. Per row: relationship_* CSV columns or field in JSON bulk. |
childEnrichmentPolicy | No | all_active (default), by_root_type, or basic_only β automatic + depth > 0. See Child enrichments & monitoring. |
monitoringApplyToRelationships | No | true / false β when false, monitoring applies to main entities only (no monitoring.relationships). Default true when depth > 0 if omitted. |
depth | No | 0β5 β automatic mode only |
isClient | No | true / false |
status | No | Entity status literal (batch) |
attributes | No | JSON (batch) |
nationality | No | ISO2 |
monitoring | No | JSON β both modes (relationships key: automatic + depth > 0 only) |
reportRecipientEmails | No | JSON array |
emailLocale | No | en / es / pt |
Success Response
{
"success": true,
"jobId": "bulk-entity-β¦",
"importMode": "manual",
"totalItems": 42,
"message": "Bulk import queued"
}
Child Enrichments & Monitoring
Automatic mode withdepth > 0 creates shareholders (company roots) or related entities (person roots). Two batch fields control how enrichments and watchlist monitoring apply to those children:
childEnrichmentPolicy | Main entity | Company root β shareholders | Person root β related entities |
|---|---|---|---|
all_active (default) | As configured | All active enrichments for each child type (same as before) | Same |
by_root_type | As configured | All active enrichments except global_gueno_sanctions_enrichment (check-only / no watchlist on children) | Basic data only from the root provider snapshot (no child enrichment pipeline) |
basic_only | As configured | Basic data only | Basic data only |
monitoringApplyToRelationships: when false, the monitoring JSON applies to main entities only (monitoring.main); related entities are not added to watchlists even if enrichments run on them. Recommended false with by_root_type when the main entity should enter sanctions monitoring but children should not.
Example (mixed company + person CSV, depth 1, main watchlist only, differentiated children):
-F 'entityImportMode=automatic' \
-F 'depth=1' \
-F 'childEnrichmentPolicy=by_root_type' \
-F 'monitoringApplyToRelationships=false' \
-F 'monitoring={"main":{"global_gueno_sanctions_enrichment":{"watchlist":true}}}'
autoExecuteIntegrationsShareholders in JSON bulk (POST /entities/bulk/automatic) or relationship_* CSV columns still override the batch policy for that item.
Manual vs. Automatic (Same Job Queue)
| Manual | Automatic | |
|---|---|---|
| Same as single-entity API | Create entity (manual) | Create entity automatically |
| Basic data by tax ID (Nosis/CPF / Chile; AR fallback ARCA) | No | Yes β blocking |
| If basic data fails | N/A (no basic-data step) | No entity on that row; next row runs (unless stopOnFirstError) |
| If extra enrichments fail | Entity kept | Entity kept |
suggested_name | Required every row | Recommended |
| Country (ISO2) | Required β batch country and/or CSV country_code (row wins) | Same (automatic: AR, BR, CL only) |
| Enrichments | Optional (autoExecuteIntegrations / CSV row) | Default all active; optional pick list |
| Risk matrices | Yes | Yes |
Shareholder depth | No | Yes (0β5) |
| Countries | Any valid ISO2 | AR, BR, CL |
Limits
| Value | |
|---|---|
| Files per request | 1 CSV (file field) |
| Max rows per import | By organization plan, then a hard cap of 20,000: Freemium 4,000 β Startup 12,000 β Growth / Enterprise / Usage based 20,000. See Bulk imports overview β Limits by plan. |
| Server cap (optional) | BULK_AUTOMATIC_ENTITY_MAX_ITEMS may only lower the effective limit (never raise it above 20,000) |
| Over limit | 400 TOO_MANY_ITEMS |
| Same-org entity job already live | 409 JOB_IN_PROGRESS (one queued/running entity import per organization) |
| Same-org transaction batch already queued | 409 JOB_ALREADY_WAITING (at most one waiting job per organization) |
| Same-org transaction batch running (and nothing already waiting) | 202 queued (code: "QUEUED_WAITING_PREVIOUS_JOB", queue.waitingForOrgJob: true); starts when that job finishes |
| Global processing slots full | 202 with code: "QUEUED_WAITING_SLOT", status: "queued" and queue (max 2 orgs processing entity imports at once; yours waits) |
Default When Mode Omitted
| Endpoint | Default |
|---|---|
POST /batch-import/import/entities (this page) | manual |
Hub vs. API
| Flow | Endpoint | Default mode |
|---|---|---|
Entities tab (/bulk-imports?tab=entities) | This endpoint (POST /batch-import/import/entities) | User picks in UI (UI default: automatic β send entityImportMode=automatic) |
| Multipart API (this page) | POST /batch-import/import/entities | Manual if entityImportMode omitted |
Custom (?tab=custom) | POST /batch-import/import/entities + mappingId | UI selector (default: automatic) |
Was this page helpful?