{BASE} is the Authentica Integration API base URL: https://authentica-merge-integration.t2.sa. Base path: {BASE}/api/V1/Verify

The whole partner surface — three calls

That is all of it.
Authentica never calls your server. There is no callback, no webhook, no signature to verify, no delivery log, no retry schedule, no assertion and no /introspect. Your server always asks; it is never told. If your integration plan contains a route that receives a result, delete it.
There is no per-use-case endpoint either: the same session verifies a login, a payment, a profile change, or any other action you choose to protect. What differs is your own logic around it and the operationSensitivity you send.

The shape, in one paragraph

This is the OAuth authorization-code shape with OTP in the middle. The front channel carries an opaque referencesession_id — and the back channel redeems it with your client credentials. Stripe Checkout does exactly this with ?session_id=; Adyen does it with redirectResult. When a security reviewer asks what stops someone forging the return, the answer is the same as for those: the return URL carries nothing worth forging, and the result comes from an authenticated call you make.

Authentication

Every call uses HTTP Basic:
Missing or unparseable Basic header → HTTP 401 (empty body). Wrong credentials → JSON envelope with errorCode: "unauthorized". Sessions are scoped to the calling client: a sessionId created by another client is invisible to you.

Response envelope

Every JSON response uses:
Read business data from result. On failure, check errorCode / errorMessage and the HTTP status.

Hosted UI (not called by your backend)

POST /session returns a bare verifyUrl (no query string) plus a single-use handoff token. The browser opens the hosted page by POSTing handoff to verifyUrl as a form field — never by navigating to a URL:
Use verifyUrl as returned — do not build it yourself and do not append anything to it. It may use a different host than {BASE}, and GET {verifyUrl} with any query string returns 400. The hosted page is always a full top-level page: it sends frame-ancestors 'none' and cannot be embedded in an iframe. The binding field in the response is "form_post" — that describes how the page is opened, and nothing else in the flow.

The return leg

When the user finishes, the browser is redirected to your registered returnUrl with an ordinary top-level GET:
Nothing there is secret. session_id is an identifier and state is your own value; both are useless without your client secret. The redirect is only how the user gets home — the outcome comes from GET /session/{sessionId}, and only from there.

Partner-facing vs internal

Partners do not call the front-channel endpoints the hosted page uses (/api/V1/Verify/otp, /start, /resend, the WebAuthn routes). Those belong to the hosted UI. The three calls in the table above are the entire integration surface. Curl examples: Backend overview. Field reference: Create session · Session status. Browser side: Frontend overview.