Aller au contenu

Importing a list

Ce contenu n’est pas encore disponible dans votre langue.

Your institution can keep its own watch lists in SpeculaPro: an internal list of people you won’t deal with, a list your group sends you, or any list SpeculaPro doesn’t fetch. You write the list as a simple file and import it. Each import is a new version of the list.

A list you import belongs to your workspace alone. No other workspace on the installation sees it, its versions or the matches against it.

You need screening.manage. An import can need a second person’s approval.

The key of a list of your own is import:<name>, for example import:internal-watchlist.

Rule Detail
Length of <name> 2 to 57 characters
Characters Lower-case a-z and 0-9. After the first character, also -, _ and .
First import Creates the list. Give it a display name: Name of the list in the app, ?name= through the API
Later imports Store a new version of the same list. Send ?name= again only to rename it
How many At most 20 lists of your own per workspace

In the app you don’t type the key. You type the list’s name and SpeculaPro makes the key from it: accents are dropped, letters become lower-case, and anything that isn’t a-z, 0-9, ., _ or - becomes a hyphen. Internal watch list gives import:internal-watch-list, shown under the field as you type. The name must give at least two such characters.

What is refused, before anything else happens and before any approval request is made:

You send Answer
ng-nigsac, gh-domestic, uemoa-gel or the key of any other built-in list 403, … is one of the installation’s lists, the same for every workspace: the operator imports it (speculapro screening import-list, or a signed list bundle). A workspace imports its own lists as import:<name>
An import:<name> key the installation already uses for a list of its own 403, … is one of the installation’s lists; give your own list another name
A key that breaks the naming rules 422, an imported list’s key is import:<name> (2 to 57 characters: a-z, 0-9, - _ .)
A twenty-first list 422, a workspace keeps at most 20 lists of its own

Only your workspace. Another workspace can have a list with the same key, for example import:internal-watchlist; it is a different list, and neither workspace sees the other’s. The database enforces this for every read and write.

Some official lists are published only as web pages, PDFs or gazette notices: Nigeria’s NIGSAC list (ng-nigsac), Ghana’s domestic designations (gh-domestic) and the UEMOA asset-freezing lists (uemoa-gel). SpeculaPro can’t fetch those, so someone transcribes the publication into a file in the format below.

These are the installation’s lists, the same for every workspace, so a workspace does not import them:

  • On a self-hosted installation, the operator imports the file from the command line: speculapro screening import-list ng-nigsac nigsac-2026-06-18.csv. See Screening lists for operators.
  • On the hosted service, SpeculaPro operations load them.

If your workspace needs names from such a publication before the installation’s list has them, import them into a list of your own, for example import:nigsac-interim, and tick it under Settings → Screening.

A file is either CSV or XML. SpeculaPro tells which from the first character.

The import endpoint accepts files up to 2 MiB. This limit is the endpoint’s own: the server’s general request limit (SP_HTTP_MAX_BODY_BYTES, 1 MiB by default) does not shorten it. A larger file is refused with 413 request body too large. Lists of a few hundred entries are far smaller.

UTF-8, comma-separated, with a header row. Columns can be in any order, and columns SpeculaPro doesn’t know are ignored.

# published: 2026-06-18
key,kind,name,aliases,dob,nationality,ids,programme,listed_on,remarks
NG-0042,person,Musa Example Bello,Musa E. Bello|Moussa Bello,1969|1975,NG,passport:A00000000:NG,NIGSAC,2024-03-18,Illustrative entry
NG-0043,organization,Example Trading Company Ltd,Example Trading,,NG,company_reg:RC000000:NG,NIGSAC,2024-03-18,
Column Required Meaning
key Yes The publisher’s reference for the entry, unique in the list. Keep it the same from one import to the next, or the entry looks removed and added again
name Yes The main name
kind No person (the default; individual is accepted), organization (also organisation, entity, company), vessel (also ship) or aircraft. Anything else is read as unknown
aliases No Other names, separated by |
dob No Dates of birth, separated by |: YYYY, YYYY-MM, YYYY-MM-DD or DD/MM/YYYY
nationality No Two-letter country codes or English country names, separated by |
ids No Identity documents, separated by |, each type:number or type:number:country. The type is passport, national_id, tax_id, company_reg, imo or other
programme No The sanctions programme or regime, several separated by |
listed_on No The date of listing
remarks No Free text

An optional first line # published: YYYY-MM-DD gives the publication date shown on the version.

<screening-list xmlns="https://speculapro.com/ns/screening-list/1" published="2026-06-18">
<entry key="NG-0042" kind="person">
<name>Musa Example Bello</name>
<alias>Musa E. Bello</alias>
<alias>Moussa Bello</alias>
<dob>1969</dob>
<nationality>NG</nationality>
<id type="passport" country="NG">A00000000</id>
<programme>NIGSAC</programme>
<listed-on>2024-03-18</listed-on>
<remarks>Illustrative entry</remarks>
</entry>
</screening-list>

The root element must be screening-list in the namespace https://speculapro.com/ns/screening-list/1. Repeat alias, dob, nationality, id and programme as often as needed.

Problem Answer
Empty file, no header row, or no key and name columns 422, not a list in the expected format: …
An ids value without a : 422, line N: ids must be type:number[:country]
XML with the wrong root or namespace 422, the root must be <screening-list xmlns=…>
No usable entries 422, the list has no entries

Rows with no key or no name are skipped without an error, and so is a row that repeats an earlier key. Count the entries in the answer against your source to be sure nothing was dropped.

You need screening.manage. Without it the Import a list button isn’t shown.

  1. Write the complete current list into a CSV or XML file of at most 2 MB.

  2. Have a second person check it against its source. A typing mistake in a name is a missed match.

  3. Open Settings → Screening. In the Sanctions lists panel, select Import a list.

  4. Under What to load, choose A new version of your list, or A new list. A workspace with no list of its own yet isn’t asked: the import starts a new list.

  5. For a new list, type the Name of the list, for example Internal watch list. The key it will get appears under the field.

  6. Under File, select Choose a CSV or XML file and pick your file. A file whose name ends in .xml is sent as XML; any other as CSV. A file over the limit shows That file is larger than 2 MB. and can’t be sent.

  7. Select Import.

  8. Read the result:

    Message Meaning
    Version N stored: X entries (A added, C changed, R removed). The new version is stored. Check the counts against your source
    This file has the same content as the current version. Nothing was stored. The entries are the same as the current version’s
    This file is dated before the current version. The newer version stays. The file’s # published: date is earlier than the current version’s
  9. Select Done. If the list is new, tick it under Sanctions lists and select Save. Importing a list does not by itself make your workspace screen against it.

Not sure about the format? In the import panel, open What the file must look like. It lists the columns and offers Download a sample file (watch-list-sample.csv, two made-up entries) to start from. The full format is under The import format.

The Import a list sheet: What to load set to A new list, the Name of the list box with the key import:sanctions-desk-watch-list shown under it, the chosen file internal-watch-list.csv, the What the file must look like section open with its list of columns and the Download a sample file link, and the Import button The Import a list sheet: What to load set to A new list, the Name of the list box with the key import:sanctions-desk-watch-list shown under it, the chosen file internal-watch-list.csv, the What the file must look like section open with its list of columns and the Download a sample file link, and the Import button The Import a list sheet after an import: Version 1 stored: 3 entries (3 added, 0 changed, 0 removed), the reminder to tick the list under Sanctions lists if it is not screened yet and then save, and the Done button The Import a list sheet after an import: Version 1 stored: 3 entries (3 added, 0 changed, 0 removed), the reminder to tick the list under Sanctions lists if it is not screened yet and then save, and the Done button

An import falls under the approval rule Screening sources and thresholds, which is on by default once two people hold screening.approve. See Approvals.

When the rule applies, the import is not stored straight away:

  1. After you choose Import, SpeculaPro asks why you are making the change, in the same dialog as every other change that needs approval. Type the reason and confirm. If you cancel, nothing is sent.
  2. The file is sent again with your reason. The import panel closes, and a message says the request is waiting for approval.
  3. Someone else with screening.approve approves or rejects it under Approvals. The request shows the list, the file’s size and the start of its SHA-256. On approval the version is stored, exactly as if you had imported it directly.

Through the API, send the reason in the X-Change-Reason header, as below.

  1. Write and check the file as in steps 1 and 2 above.

  2. Send it, signed in as someone with screening.manage:

    Terminal window
    curl -X POST "https://speculapro.example/api/v1/screening/sources/import:internal-watchlist/import?name=Internal%20watch%20list" \
    -H "Content-Type: text/csv" \
    -H "X-Change-Reason: Watch%20list%20update%20of%2018%20June" \
    -H "Origin: https://speculapro.example" \
    -b cookies.txt \
    --data-binary @watchlist-2026-06-18.csv

    ?name= gives a new list its display name. Leave it out on later imports to keep the name.

  3. Read the answer.

    • 200 with the result: the version was stored.

      {"source": "import:internal-watchlist", "version_id": "0199…", "seq": 3, "unchanged": false,
      "entries": 214, "added": 2, "changed": 1, "removed": 0}

      "unchanged": true means the file has the same entries as the current version, and nothing was stored.

    • 202: the import is waiting for a second person. It is stored when they approve it under Approvals. The request shows the list, the file’s size and the start of its SHA-256 fingerprint, so the approver can check they are approving the file they were shown. If the list gets another version before the approval, the request is closed as out of date and you send the file again.

    • 428: approval is required and you didn’t send a reason. Send X-Change-Reason.

    • 403 or 422 about the key: see Naming your list.

    • 413: the file is larger than 2 MiB.

  4. Open Settings → Screening and check the list’s Current version, Entries and, under Versions, the Changes column. Your list is marked this workspace’s own list.

  5. If the list is new, tick it under Sanctions lists and Save. Importing a list does not by itself make your workspace screen against it.

Within about a minute the worker applies the new version: people who might match an added or changed entry are screened again, and matches on removed entries are marked delisted.

What you see Why What to do
No Import a list button You don’t hold screening.manage Ask an administrator, or have someone who holds it import the file
That file is larger than 2 MB. The file is over the limit A watch list of a few thousand entries is far smaller. Remove columns you don’t need, or split the list into two lists
Not sent: a change that needs approval needs a reason. Approval applies and you closed the reason dialog without giving one Choose Import again and give a reason. See When approval is required
not a list in the expected format: …, line N: ids must be type:number[:country] or the list has no entries The file doesn’t follow the format See What is checked. Compare your file with the sample
a workspace keeps at most 20 lists of its own You chose A new list and already have twenty Load a new version of an existing list instead
… is one of the installation’s lists; give your own list another name The name you typed gives a key the installation already uses Choose another name
The list has a version but nobody matches it The list isn’t ticked Tick it under Sanctions lists and select Save
Fewer entries than you expected Rows with no key or no name, and rows repeating a key, are skipped Fix those rows and import the complete file again

Each stored version is written to your workspace’s audit log as screening.list.version, under the person who imported it (or, with approval, the person who proposed it), with the list, the version number, the entry count and how many entries were added, changed and removed.

Before workspaces had lists of their own, every imported list belonged to the installation, and a workspace on a self-hosted installation could import ng-nigsac, gh-domestic, uemoa-gel and import:<name> lists for everyone. After the upgrade:

  • Lists imported before the upgrade stay the installation’s lists. They keep working, every workspace that ticked one still screens against it, and only the operator can update them.
  • To update one, ask your operator, or import the names into a new list of your own under a different key and tick it.

See Upgrading: notes for specific migrations.