---
title: Integrate your backend
description: How a back-end service should call Human Plugin — what to store, how to poll, how to read the outcome and how to handle failures.
canonical: https://developer.unico.io/human-plugin/integrations/backend
locale: en
generated_by: markdown-export
---

# Integrate your backend

The checklist for calling Human Plugin from a server-side service.

Human Plugin is meant to be called by your back-end only. Do not expose it to browsers or mobile apps: it has no inbound authentication.

## 1. Create

### curl

```bash
curl -X POST "$HUMAN_PLUGIN_URL/v1/processes" \
  -H 'Content-Type: application/json' \
  -d '{
    "flow": "api+humantoken",
    "clientId": "client-a",
    "correlationId": "onboarding-001",
    "credential": { "type": "DUI_TYPE_NG_BVN", "value": "<document number>" },
    "imageBase64": "<base64 selfie>"
  }'
```

### Node.js

```javascript
const response = await fetch(`${process.env.HUMAN_PLUGIN_URL}/v1/processes`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    flow: 'api+humantoken',
    clientId: 'client-a',
    correlationId: 'onboarding-001',
    credential: { type: 'DUI_TYPE_NG_BVN', value: documentNumber },
    imageBase64,
  }),
  signal: AbortSignal.timeout(60_000),
});

const body = await response.json();
if (response.status !== 201) {
  // body is { message, details }
  throw new Error(`Human Plugin ${response.status} ${body.message}`);
}
const { id, state, data } = body;
```

Set your client timeout to **at least 60 seconds**: a create can take up to 30 seconds to process, plus the database steps. The `id` comes only in the create answer, so a client that gives up early can lose a process that finishes.

## 2. Persist what you will need later

| Keep | Because |
| --- | --- |
| `id` | The handle for `GET` |
| Journey `token` and `link`, if any | Returned only on the create response, never stored by Human Plugin |
| Your `correlationId` | It must be unique. Generate a new one for every attempt, retries included, except after a `503` |

## 3. Read the outcome

1. If `state` is `PROCESS_STATE_FINISHED`, read the result from `data`: `humanToken` (or `humanTokenMatch` in a revalidation), `liveness` and `ndocs`. Finished is not the same as approved.
2. If `state` is `PROCESS_STATE_CREATED`, poll `GET /v1/processes/{id}` with backoff until it changes. Nothing else advances the process.
3. If `state` is `PROCESS_STATE_FAILED`, the process ended without a result. Start a new one if your flow allows it.

## 4. Use the intelligence

`data.ndocs` tells you what the person has done with you: with how many of your clients and documents they were seen, and when. Use it in your decision together with the Human Token, and remember it can be absent. See [Intelligence](/human-plugin/get-started/intelligence).

## 5. Failure handling

- Do not retry `500` or `502` on create automatically. See [Errors and retries](/human-plugin/api-reference/errors-and-retries).
- Retry `503` on create with the same `correlationId`, and any failure on `GET`, with backoff.
- `409` means the `correlationId` is taken. Never reuse one.
- Alert on repeated `503`: it means Human Plugin cannot reach its database.

## Operational expectations

- Call Human Plugin from the same network as the container. Terminate TLS in front of it if the path crosses untrusted networks.
- One Human Plugin installation is one isolation boundary. Different clients, brands or environments that must not share intelligence need separate installations and databases, each with its own intelligence.