POST Verify Identity / Re-Login

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

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:

  • 1Password-sourced credential — omit params (or send {}). The engine re-resolves the username and password from the bound vault item.
  • 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 1Password-sourced credential — the engine re-resolves 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": {
      "vault_id": "abcd1234",
      "item_id": "wxyz5678",
      "fields": ["username", "password"]
    },
    "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 item locator (vault_id, item_id, fields). 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 1Password-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 integration 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-resolving a bound 1Password credential, before the wheel runs:

CodeHTTPWhen
SOURCE_NOT_FOUND400The credential's bound integration was deleted — reconnect the source
SOURCE_REVOKED4001Password rejected the stored token — reconnect the source in the dashboard
SOURCE_ITEM_NOT_FOUND400The bound vault/item no longer exists
SOURCE_ITEM_MISSING_FIELDS400The item has no username or password
SOURCE_INACTIVE400The bound source is not active
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) 1Password-sourced credential — no params; fields re-resolved from the bound item
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).