Bulk beneficiary import

Goal

Upload a spreadsheet or CSV of beneficiary accounts (CLABEs, cards, or DiMo numbers), review how each row was classified, fix the correctable errors, and commit the import — creating all valid accounts in a single operation.

Prerequisites

  • An active API key (veriko_…) with the beneficiaries:create permission.
  • A file in one of the supported formats: CSV, XLS, XLSX, TXT, or PDF. Maximum size: 20 MB.
  • XLSX/XLS sheets allow up to 10,000 rows and 64 columns; XLSX formulas are read as text without calculation. PDFs allow up to 50 pages.
  • Only one import job may be active (non-terminal) at a time per user. Cancel or wait for the previous job to finish before uploading a new file.

Steps

1. (Optional) Download the template

For best results, use the canonical template — the parser handles it without needing AI:

curl 'https://api.veriko.mx/v1/beneficiaries/imports/template' \
  -H 'Authorization: Bearer veriko_••••' \
  --output plantilla-beneficiarios.csv

The template CSV has the columns alias, cuenta and banco. Fill in your data and save. The bank is derived from the CLABE prefix or card BIN; for a DiMo phone, enter it in banco.

2. Upload the file

Send the file as multipart/form-data. Choose the parse_mode:

  • template — the file follows the canonical column headers (recommended).
  • free — any structure; the system extracts accounts automatically with AI fallback for unstructured formats.
curl -X POST 'https://api.veriko.mx/v1/beneficiaries/imports' \
  -H 'Authorization: Bearer veriko_••••' \
  -F '[email protected];type=text/csv' \
  -F 'parse_mode=template'

Response 202 — job created:

{
  "data": {
    "type": "beneficiary_import",
    "id": "42",
    "attributes": { "status": "pending" }
  }
}

3. Poll until preview_ready

The job passes through the states pending → parsing → preview_ready. Poll GET /v1/beneficiaries/imports/{id} every 2 seconds:

curl 'https://api.veriko.mx/v1/beneficiaries/imports/42' \
  -H 'Authorization: Bearer veriko_••••'

When status is preview_ready, the response includes per-bucket counters:

{
  "data": {
    "id": "42",
    "attributes": {
      "status": "preview_ready",
      "total_rows": 150,
      "valid_count": 120,
      "correctable_count": 20,
      "fatal_count": 5,
      "duplicate_count": 5
    }
  }
}

Bucket meanings:

BucketDescription
validRow is ready to commit as-is.
correctableRow has a fixable issue (e.g. missing bank code for a DiMo phone). Edit it before committing. A phone number without a valid bank is not saved until you choose its bank.
fatalRow cannot be fixed (e.g. account number fails the checksum). It will be skipped at commit.
duplicate_accountThe account number already exists in your beneficiary list. It will be skipped at commit.
duplicate_aliasAlias collision — the commit will append a numeric suffix automatically.

4. Review and fix rows in the preview

Fetch the preview to see the individual rows, optionally filtering by bucket:

# Only correctable rows
curl 'https://api.veriko.mx/v1/beneficiaries/imports/42/preview?buckets[]=correctable' \
  -H 'Authorization: Bearer veriko_••••'

To fix a row (for example, assign a bank code to a DiMo phone number):

curl -X PATCH \
  'https://api.veriko.mx/v1/beneficiaries/imports/42/rows/102' \
  -H 'Authorization: Bearer veriko_••••' \
  -H 'Content-Type: application/json' \
  -d '{
    "parsed_account_type": "phone",
    "parsed_bank_code": "40012",
    "parsed_bank_name": "BBVA MEXICO"
  }'

The server re-processes the row immediately and returns its updated status. If the override resolves the error, status changes from correctable to valid.

Five fields are editable per row: parsed_account, parsed_label, parsed_account_type, parsed_bank_code, parsed_bank_name.

5. Commit the import

The job and the preview's meta.job include plan_cap: max is the plan cap (-1 means uncapped), current counts active accounts and required adds new accounts and archived accounts that will be reactivated.

When exceeded=true, the console disables Confirm. You can archive an active account or remove rows until the batch fits the allowance. To remove a row:

curl -X DELETE 'https://api.veriko.mx/v1/beneficiaries/imports/42/rows/102' \
  -H 'Authorization: Bearer veriko_••••'

Returns 204 and recalculates groups and counters, preserving overrides on remaining rows. Only allowed in preview_ready; afterwards it returns 422 job_not_editable. The server checks the allowance again on confirmation and returns 422 plan_cap_exceeded if it is still exceeded. No partial batch is created.

When you're satisfied with the preview, trigger the commit:

curl -X POST 'https://api.veriko.mx/v1/beneficiaries/imports/42/commit' \
  -H 'Authorization: Bearer veriko_••••'

Response 202 — commit enqueued:

{
  "data": {
    "id": "42",
    "attributes": { "status": "committing" }
  }
}

Poll GET /v1/beneficiaries/imports/42 until status is completed or failed. On completion, the response shows committed_count and skipped_count:

{
  "data": {
    "attributes": {
      "status": "completed",
      "committed_count": 140,
      "skipped_count": 10
    }
  }
}

Commit rules: valid and correctable rows are persisted. fatal and duplicate_account rows are skipped. A phone number without a valid bank is correctable with the code bank_code_required_for_phone (or invalid_bank_code if the bank does not exist) and is fixed by choosing the bank in that row of the preview; if it still has no bank when you confirm, it is not saved silently: the row is skipped, becomes fatal with that same code and counts in skipped_count, and plan_cap.required does not count it. Previously archived accounts with the same number are reactivated instead of duplicated and keep their alias if the row brings none. If an account in the file is registered through another channel between preview and commit, that row is skipped as duplicate_account and the rest of the batch is saved.

6. (Optional) Cancel before committing

If you need to start over, cancel the job while it is in pending, parsing, or preview_ready:

curl -X DELETE 'https://api.veriko.mx/v1/beneficiaries/imports/42' \
  -H 'Authorization: Bearer veriko_••••'

Returns 204 on success.

What's next

  • View the created beneficiaries: GET /v1/beneficiaries.
  • Add or update individual beneficiaries: POST /v1/beneficiaries, PUT /v1/beneficiaries/{id}.
  • Export the full list for reconciliation: GET /v1/beneficiaries/export.