top of page

Create an embedded reporting session

Keep long-lived reporting credentials on your server and issue scoped, expiring sessions.

Use this flow for reporting components

Embedded reporting components authenticate with a short-lived session created by your backend. The Payment Component does not use this session pattern: its public tokenization key and payment-processing private key are a separate flow. Confirm the reporting product and account access before wiring a component. Context Credential boundary Gateway reporting session Gateway credential in server request body; scoped to merchant_id Merchant Central reporting session Merchant Central API key and tenant_id in server request body Payment Component Public tokenization key in browser; private payment key stays on server

Create a Gateway sandbox session

The documented endpoint is POST https://sandbox.nmi.com/api/v5/embedded-reporting/sessions. Send Accept and Content-Type as application/json. The schema supplies credentials in the JSON body rather than declaring a payment-style Authorization header. Gateway api_key must begin v4_secret_; its length is at most 255 characters. merchant_id is a numeric string of at most 20 digits. Explicitly set environment to sandbox because the field defaults to production. POST /api/v5/embedded-reporting/sessions HTTP/1.1 Host: sandbox.nmi.com Accept: application/json Content-Type: application/json { "gateway": { "api_key": "v4_secret_<sandbox-gateway-secret>", "merchant_id": "<authorized-numeric-merchant-id>", "environment": "sandbox" } } Placeholders are not credentials. Resolve the merchant ID from the authenticated user’s authorized account mapping, never an unchecked browser input.

Use Merchant Central as an alternative source

For a Merchant Central-backed component, send the merchant-central object instead of gateway. tenant_id is the subdomain portion of the Merchant Central instance, at most 200 characters; api_key is at most 255 characters and merchant_id is a numeric string of at most 20 digits. There is no documented environment field on this branch. Confirm the intended non-production tenant/account before using it. { "merchant-central": { "api_key": "<merchant-central-secret>", "tenant_id": "<authorized-tenant-subdomain>", "merchant_id": "<authorized-numeric-merchant-id>" } } Specify exactly one credential source. The narrative explicitly says sending both gateway and merchant-central causes validation failure, even though the published schema uses anyOf.

Return only the short-lived result

On success, the API returns session_token and expires_at. The narrative describes a default lifetime of 15 minutes; use the returned expiry rather than calculating a guaranteed duration yourself. Reporting components that expect fetchSessionId with sessionToken/expiresAt need an explicit adapter between these naming conventions. Reporting SessionResponse declares expiresAt as a number; ExportData has a separate string expiresAt for download expiry. Do not confuse these contracts. The session docs do not specify timestamp units: verify seconds versus milliseconds against the installed component version and supply that choice explicitly. // timestampUnit must match the installed reporting component contract. export function componentSession(apiResult, timestampUnit) { const expiryMs = typeof apiResult?.expires_at === 'string' ? Date.parse(apiResult.expires_at) : NaN; if (typeof apiResult?.session_token !== 'string' || !apiResult.session_token || !Number.isFinite(expiryMs)) { throw new Error('Invalid reporting session response'); } if (timestampUnit !== 'seconds' && timestampUnit !== 'milliseconds') { throw new Error('Verify the installed component timestamp unit'); } return { sessionToken: apiResult.session_token, expiresAt: timestampUnit === 'seconds' ? Math.floor(expiryMs / 1000) : expiryMs }; }

Renew with the same access checks

Your application-owned session endpoint should check user and merchant access each time a component requests a session. Keep long-lived credentials in server configuration and avoid caching sessions across merchants or users. On expiry, request a replacement through that authorized backend rather than exposing the secret to the browser. Authenticate the application user and resolve authorized merchant access. Select one server-held credential source and create the session. Validate the returned session_token and expires_at. Return only the scoped temporary result using the component’s callback contract. Repeat authorization on renewal and discard sessions after logout or account changes.

Handle documented errors and source limitations

The endpoint documents HTTP 401 for missing/invalid authentication and 422 for validation, including errors keyed by field name such as gateway.merchant_id. Treat these as configuration or input issues, not permission to switch credential sources automatically. The published schema marks the body optional, but the guide’s usable flow specifies one credential object; do not rely on an empty body. The published server list supplies the sandbox URL only, so this guide does not invent a production reporting hostname. Result Handling 200 with valid session fields Pass temporary session to the authorized component 401 Check server credential and selected account; keep secret out of diagnostics 422 Correct named fields and ensure only one credential source Expired session Reauthorize and request a new scoped session Unexpected response Show recoverable reporting error; do not leak raw payloads Transaction history overview Deposit history overview Deposit summary overview

Join the community and get the latest biz news & tips

Thanks for submitting!

© 2025 Betterpay. All Rights Reserved.

bottom of page