> ## Documentation Index
> Fetch the complete documentation index at: https://docs.topograph.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Register Credentials

> Store your own register logins per workspace to unlock credential-gated data

## Overview

Some registers do not serve their data to a third party. They serve it to **you**, under your own account, and log the access on their side. Two cases exist:

* **Access-gated registers.** The register only grants access to the obliged entity performing the check. Germany's Transparenzregister works this way: without your own login, the data cannot be retrieved at all.
* **Enrichment registers.** Topograph can always return the public view, but an account holding elevated roles at the register sees more. France's INPI works this way: accounts authorised for the beneficial-owner register get un-redacted personal fields.

For both cases you store your own register login in Topograph's **credential vault**. Credentials are held **per workspace**, so a reseller can give each client workspace its own register account, and each client's data stays attached to their own credential.

<CardGroup cols={3}>
  <Card title="Per-Workspace Scope" icon="buildings">
    Each workspace holds its own set of register logins, with fallback to the default workspace
  </Card>

  <Card title="Write-Only Storage" icon="lock">
    Credentials are encrypted on write. No endpoint and no screen ever returns them back
  </Card>

  <Card title="Isolated Results" icon="shield-halved">
    Data fetched under your login is cached against your account only, never shared
  </Card>
</CardGroup>

***

## Supported Registers

| Register                     | Source key               | What it changes                                                                                               | Without a credential                                   |
| ---------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
| Germany: Transparenzregister | `de_transparenzregister` | Unlocks `ultimateBeneficialOwners` for Germany                                                                | The datapoint returns `account_configuration_required` |
| France: INPI                 | `fr_inpi`                | Un-redacts UBO personal fields (date of birth, nationality, address) and returns the richer `ubo_extract` PDF | The public, redacted view is returned                  |

The list above is the current one. `GET /v2/vault/sources` is authoritative and also tells you the exact payload each register expects:

```bash theme={null}
curl "https://api.topograph.co/v2/vault/sources" \
  -H "x-api-key: YOUR_API_KEY"
```

```json Response theme={null}
[
  {
    "key": "fr_inpi",
    "format": "password_pool",
    "fields": [
      {
        "name": "accounts",
        "type": "array",
        "required": true,
        "secret": false,
        "item": {
          "fields": [
            { "name": "username", "type": "string", "required": true, "secret": false },
            { "name": "password", "type": "string", "required": true, "secret": true }
          ]
        }
      }
    ]
  },
  {
    "key": "de_transparenzregister",
    "format": "email_password",
    "fields": [
      { "name": "email", "type": "string", "required": true, "secret": false },
      { "name": "password", "type": "string", "required": true, "secret": true }
    ]
  }
]
```

<Info>
  Field names match the login form of the register itself, so what you type is what we send. Nothing is translated in between.
</Info>

***

## How Resolution Works

A credential is looked up from the workspace the request is tagged with, then from the default workspace if that workspace has none of its own.

```mermaid theme={null}
flowchart TD
    A["Request tagged acme-paris"] --> B{"Credential on acme-paris?"}
    B -->|yes| C["Run under the acme-paris login"]
    B -->|no| D{"Credential on the default workspace?"}
    D -->|yes| E["Run under the default workspace login"]
    D -->|no| F["Access-gated: account_configuration_required<br/>Enrichment: public view"]
```

This gives you two working patterns:

<AccordionGroup>
  <Accordion title="One credential for the whole account">
    Store the login on the **default** workspace and leave the other workspaces empty. Every workspace inherits it, so all requests run under the same register account. Use this when your organisation holds one register account and workspaces exist only for cost attribution.
  </Accordion>

  <Accordion title="One credential per client">
    Store a different login on each workspace. A request tagged `client-alpha` runs under the credential stored on `client-alpha`. Nothing is inherited, because the workspace has its own entry. Use this when you are a reseller and each of your clients is the obliged entity for their own checks.
  </Accordion>

  <Accordion title="Default plus overrides">
    Store a house login on the default workspace and add a specific one only on the workspaces that need it. Workspaces without their own entry fall back to the default. Deleting a workspace's entry silently returns it to the inherited one.
  </Accordion>
</AccordionGroup>

<Note>
  Company requests resolve credentials from the workspace on the request. [Search](/essentials/search) resolves them at account level, so a register login stored on any of your workspaces is used for search regardless of the workspace header.
</Note>

***

## Configuring a Credential

### From the dashboard

Go to **Workspaces** in [app.topograph.co](https://app.topograph.co), open a workspace and select **Vault**. Each supported register is listed with the fields it needs and shows whether a credential is currently configured.

Managing credentials is restricted to admins of your organisation. Non-admin members do not see the screen.

### From the API

Credentials are written with a `PUT` per register. The path names the workspace, so the entry always lands on the workspace you addressed:

```bash theme={null}
curl -X PUT "https://api.topograph.co/v2/workspaces/acme-paris/vault/de_transparenzregister" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "payload": {
      "email": "compliance@acme.example",
      "password": "YOUR_REGISTER_PASSWORD"
    }
  }'
```

```json Response theme={null}
{
  "sourceKey": "de_transparenzregister",
  "origin": "customer_provided",
  "shape": "email_password",
  "ownerWorkspaceId": "253299d1-e8d0-4268-945b-f175f98bc114",
  "version": 1,
  "createdAt": "2026-08-26T09:12:00.000Z",
  "updatedAt": "2026-08-26T09:12:00.000Z",
  "expiresAt": null
}
```

<Warning>
  The response carries metadata only. The credential itself is never returned by any endpoint, so store your own copy before writing it.
</Warning>

### Registers that accept several accounts

Where the register supports it, you can register more than one login. France's INPI takes a pool: requests are spread across the accounts and fail over automatically when one is locked, expired, or rate-limited.

```bash theme={null}
curl -X PUT "https://api.topograph.co/v2/workspaces/acme-paris/vault/fr_inpi" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "payload": {
      "accounts": [
        { "username": "kyc-team-1@acme.example", "password": "FIRST_PASSWORD" },
        { "username": "kyc-team-2@acme.example", "password": "SECOND_PASSWORD" }
      ]
    }
  }'
```

A pool is replaced as a whole. To add or remove one account, `PUT` the full list again.

***

## Inspecting and Rotating

### List what a workspace holds

```bash theme={null}
curl "https://api.topograph.co/v2/workspaces/acme-paris/vault" \
  -H "x-api-key: YOUR_API_KEY"
```

The list shows only the entries the workspace owns. Inherited entries are not listed, so an empty array means "this workspace has nothing of its own", not "no credential applies".

### Check one register

```bash theme={null}
curl "https://api.topograph.co/v2/workspaces/acme-paris/vault/fr_inpi" \
  -H "x-api-key: YOUR_API_KEY"
```

This one resolves the same way a request does, so it also reports inherited entries:

```json Response theme={null}
{
  "sourceKey": "fr_inpi",
  "origin": "customer_provided",
  "shape": "password_pool",
  "ownerWorkspaceId": "a1b2c3d4-0000-0000-0000-000000000000",
  "inheritedFromWorkspaceId": "a1b2c3d4-0000-0000-0000-000000000000",
  "version": 3,
  "createdAt": "2026-05-02T08:00:00.000Z",
  "updatedAt": "2026-08-20T11:30:00.000Z",
  "expiresAt": null
}
```

When `inheritedFromWorkspaceId` is present, the credential comes from your default workspace rather than from the workspace you asked about. A `404` means neither the workspace nor the default has an entry for that register.

### Rotate

Rotation is another `PUT` on the same source key. The new payload replaces the old one and `version` increments. There is no downtime window: requests already running finish on the credential they started with, and the next request picks up the new one.

<Tip>
  Rotate before the register forces you to. Registers that lock an account after failed logins will keep locking it while an old password is still stored, so replace the entry first, then reset the password at the register if needed.
</Tip>

### Delete

```bash theme={null}
curl -X DELETE "https://api.topograph.co/v2/workspaces/acme-paris/vault/fr_inpi" \
  -H "x-api-key: YOUR_API_KEY"
```

Deleting removes the workspace's own entry. If the default workspace still holds one, the workspace goes back to inheriting it. If nothing remains, access-gated datapoints start returning `account_configuration_required` and enrichment registers revert to the public view.

***

## What Happens Without a Credential

<AccordionGroup>
  <Accordion title="Access-gated registers">
    The datapoint fails on its own, with `account_configuration_required` as the error code. The rest of the request is unaffected and the other datapoints are returned normally.

    ```json theme={null}
    {
      "request": {
        "requestId": "abc-123",
        "dataStatus": {
          "dataPoints": {
            "ultimateBeneficialOwners": {
              "status": "failed",
              "error": {
                "code": "account_configuration_required",
                "message": "This datapoint requires account-specific credentials that have not been configured."
              }
            }
          }
        }
      }
    }
    ```

    Retrying will not help until a credential is stored. See [Reliability & Errors](/guides/reliability-and-errors) for the full error contract.
  </Accordion>

  <Accordion title="Enrichment registers">
    The request succeeds and returns the public view of the data. For France that means UBO personal fields stay redacted, exactly as they are in the open data. Nothing in the response fails, so check the [France](/essentials/france) page for what the enriched view adds on top.
  </Accordion>

  <Accordion title="Monitoring">
    A [monitor](/essentials/monitoring) on a company whose datapoints are credential-gated is still created, and the response names the affected datapoint in `datapointNotices`. That datapoint is skipped on scheduled rechecks instead of failing every day, and resumes automatically on the next check once you configure the credential. You get a `monitor.datapoint_blocked` webhook when it stops and `monitor.datapoint_unblocked` when it resumes.
  </Accordion>
</AccordionGroup>

***

## Security and Isolation

<AccordionGroup>
  <Accordion title="Storage">
    Every credential is encrypted with AES-256-GCM under a per-entry key before it is written, and the encryption is bound to the account, workspace, source key and version it was written for, so a row cannot be replayed into another context. Plaintext exists only in memory, for the duration of the call to the register.
  </Accordion>

  <Accordion title="Read-back">
    No endpoint returns a stored credential, including the one that wrote it. Reads return metadata only: which register, which format, which version, when it changed. The dashboard behaves the same way, showing a register as configured without displaying the secret.
  </Accordion>

  <Accordion title="Result isolation">
    Data retrieved under your credential is cached against your account alone. No other customer can be served a result that was fetched with your login, and you are never served one fetched with someone else's. This keeps the access trail the register records on their side matching the data you actually received.
  </Accordion>

  <Accordion title="Switching and rotating">
    Moving between the public view and your own credential, or rotating the credential, always triggers a fresh fetch rather than reusing what was cached under the previous setup.
  </Accordion>
</AccordionGroup>

***

## API Reference

| Endpoint                                                                                                         | Method | Description                                       |
| ---------------------------------------------------------------------------------------------------------------- | ------ | ------------------------------------------------- |
| [`/v2/vault/sources`](/api-reference/vault/list-supported-credential-sources)                                    | GET    | List supported registers and their payload shapes |
| [`/v2/workspaces/{name}/vault`](/api-reference/vault/list-vault-entries-on-the-workspace-metadata-only)          | GET    | List the credentials a workspace owns             |
| [`/v2/workspaces/{name}/vault/{sourceKey}`](/api-reference/vault/get-one-vault-entry-by-sourcekey-metadata-only) | GET    | Check one register, including inherited entries   |
| [`/v2/workspaces/{name}/vault/{sourceKey}`](/api-reference/vault/create-or-replace-a-credential)                 | PUT    | Store or rotate a credential                      |
| [`/v2/workspaces/{name}/vault/{sourceKey}`](/api-reference/vault/delete-a-credential)                            | DELETE | Remove a credential                               |

<Tip>
  Workspaces themselves are covered on the [Workspaces](/essentials/workspaces) page. If you have never created one, your account already has a `default` workspace and every credential you store lands there.
</Tip>
