POST Verify Identity / Re-Login

Re-verify / refresh the saved login for an existing identity — works for vault-sourced and manually-entered credentials

Last updated Aug 3, 2026

POSThttps://api.anakin.io/v1/wire/credentials/verify

Re-verify and refresh the saved login for an existing identity. Wire re-runs the catalog's login wheel and refreshes the stored session cookies in place. Works for all identity types:

  • Vault-sourced credential — omit params (or send {}). The engine re-reads the login fields from the bound vault entry.
  • Manually-entered credential (Plaid-style, no bound source) — send the catalog's login params. There is nothing to re-resolve, so the fields are required.

This is the same endpoint the dashboard Re-verify action uses, for both kinds of credential.

The password is never stored. Only the issued session cookies are persisted, encrypted. When the cookies expire (see expires_at), call this endpoint again to mint fresh ones.

It behaves like POST /v1/wire/login, but targets a known identity_id instead of finding-or-creating an identity.


Request Body

{
  "identity_id": "7c3f1a2b-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
  "params": {
    "username": "alice@example.com",
    "password": "..."
  }
}
ParameterTypeDescription
identity_id requiredstring (UUID)The identity whose credential should be re-verified.
paramsobjectThe catalog's login fields (same shape as POST /login). Omit or send {} for a vault-sourced credential — the engine re-reads the fields from the bound source. Required when the credential has no bound source (manual credentials must send params).

Response

201 Created
{
  "status": "verified",
  "credential": {
    "id": "11111111-2222-3333-4444-555555555555",
    "identity_id": "7c3f1a2b-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
    "credential_type": "credentials",
    "status": "active",
    "source_id": "f1e2d3c4-0000-0000-0000-000000000000",
    "source_ref": {
      "entry": { "container": "abcd1234", "key": "wxyz5678" }
    },
    "expires_at": "2026-06-09T10:00:00Z",
    "metadata": {},
    "created_at": "2026-06-08T10:00:00Z",
    "updated_at": "2026-06-08T10:00:00Z"
  }
}
FieldTypeDescription
statusstringAlways "verified" on success
credential.idstring (UUID)Pass this as credential_id in subsequent POST /v1/wire/task calls.
credential.identity_idstring (UUID)The identity this credential belongs to
credential.credential_typestringCredential kind, e.g. credentials
credential.statusstringCredential status — active after a successful re-verify
credential.source_idstring (UUID)The bound identity source. Present only for sourced credentials (omitted for manual).
credential.source_refobjectThe bound vault locator — see source_ref. Present only for sourced credentials.
credential.expires_atstringRFC3339 UTC. When the refreshed session expires.
credential.metadataobjectFree-form metadata for the credential (always present).
credential.created_atstringRFC3339 UTC. When the credential was created.
credential.updated_atstringRFC3339 UTC. When the credential was last updated (always present).

source_id and source_ref appear only for vault-sourced credentials; they are omitted for manually-entered ones.


Error Responses

All errors return JSON of the form { "status": "error", "error": { "code": "...", "message": "..." } }. The wheel's raw error text is never echoed; only the typed code is surfaced.

Validation / setup — request rejected before the wheel runs:

CodeHTTPWhen
INVALID_BODY400Request body isn't valid JSON
INVALID_INPUT400identity_id missing; OR params empty and no source is bound to this credential (manual credentials must send params)
NOT_FOUND404Identity not found
FORBIDDEN403Identity belongs to another user
LOGIN_NOT_SUPPORTED400The catalog doesn't support credentials login, or has no published login action
LOGIN_NOT_AVAILABLE503Credentials-mode login isn't configured on this engine
LOGIN_TRANSPORT_ERROR502Could not reach the wheel runner

Source resolution — only when re-reading a vault-bound credential, before the wheel runs:

CodeHTTPWhen
SOURCE_NOT_FOUND400The credential's bound source was deleted — reconnect it
SOURCE_AUTH_FAILED400The provider rejected the stored credential — rotate or reconnect the source in the dashboard
SOURCE_FORBIDDEN400The source has no access to that container. Grant it access at the provider, then retry
SOURCE_ITEM_NOT_FOUND400The bound container or entry no longer exists
SOURCE_FIELD_MISSING400The entry can't supply a required login field. Response includes missing_fields: [...]
SOURCE_INACTIVE400The bound source is not active
SOURCE_THROTTLED429The provider is rate-limiting us. Retry shortly
SOURCE_UNREACHABLE502Could not reach the provider
SOURCE_NOT_AVAILABLE503Source resolver not configured on this engine

Wheel ran (HTTP 200, status: "error") — the request was well-formed and the wheel ran, but sign-in didn't complete. Treat any status != "verified" as failure.

CodeHTTPWhen
BAD_PASSWORD200Sign-in rejected by the site — wrong credentials
MFA_REQUIRED200Account requires multi-factor auth (not yet supported)
CAPTCHA_REQUIRED200Site is showing a captcha challenge
ACCOUNT_LOCKED200Site reports the account is locked
LOGIN_TIMEOUT200Sign-in took too long
LOGIN_PAGE_CHANGED200Site's login flow may have changed
LOGIN_NO_COOKIES200Sign-in completed but no session cookie was issued
LOGIN_INFRASTRUCTURE_ERROR200Transient Browser Connect / upstream issue — retry (same as /login)
LOGIN_FAILED200Generic fallback — sign-in failed for an unclassified reason

HTTP 200 with status: "error" is used for "the request was well-formed and the wheel ran, but the sign-in itself didn't complete." Treat any status != "verified" as failure regardless of HTTP code.


Code Examples

# (a) vault-sourced credential — no params; fields re-read from the bound entry
curl https://api.anakin.io/v1/wire/credentials/verify \
  -X POST \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "identity_id": "7c3f1a2b-4d5e-6f7a-8b9c-0d1e2f3a4b5c" }'

# (b) manual credential — send the catalog's login params
curl https://api.anakin.io/v1/wire/credentials/verify \
  -X POST \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "identity_id": "7c3f1a2b-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
    "params": {
      "username": "alice@example.com",
      "password": "your_password"
    }
  }'

Rate limit

10 requests per minute per user (each call runs a real sign-in against the target site).