Skip to main content

Authentication

All authentication-related endpoints, including SIWE login, token management, interactive agent connections, and MCP OAuth 2.1 flows.

SIWE Authentication

POST /auth/siwe/nonce

Generate a nonce for SIWE authentication.

Authentication: Public

Request Body:

{
"walletAddress": "0x1234567890123456789012345678901234567890"
}

Response:

{
"nonce": "random-nonce-string"
}

POST /auth/siwe/verify

Verify a SIWE signature and issue tokens.

Authentication: Public

Request Body:

{
"message": "SIWE message string",
"signature": "0x..."
}

Response:

{
"accessToken": "jwt-access-token",
"refreshToken": "jwt-refresh-token",
"user": {
"id": "user-id",
"ethereumAddress": "0x1234567890123456789012345678901234567890"
}
}

Token Management

POST /auth/refresh

Refresh an access token using a refresh token.

Authentication: Public

Request Body:

{
"refreshToken": "jwt-refresh-token"
}

Response:

{
"accessToken": "new-jwt-access-token",
"refreshToken": "new-jwt-refresh-token"
}

POST /auth/logout

Revoke a single refresh token.

Authentication: JWT

Request Body:

{
"refreshToken": "jwt-refresh-token"
}

Response: 204 No Content

POST /auth/logout-all

Revoke all refresh tokens for the current user across all devices.

Authentication: JWT

Response: 204 No Content

GET /auth/validate

Validate a JWT token.

Authentication: JWT

Response:

{
"valid": true,
"user": {
"id": "user-id",
"ethereumAddress": "0x1234567890123456789012345678901234567890"
}
}

GET /auth/me

Get current user information.

Authentication: JWT

Response:

{
"id": "user-id",
"ethereumAddress": "0x1234567890123456789012345678901234567890"
}

Interactive Agent Connection

These endpoints implement the interactive authentication flow, allowing AI agents to obtain API credentials by directing users to authenticate through the Nava UI.

POST /auth/connect/initiate

Generate a connection code and auth URL.

Authentication: Public

Response:

{
"code": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"authUrl": "https://testnet.navalabs.dev/connect?code=a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
}
FieldTypeDescription
codestring32-character hex connection code (128 bits of entropy)
authUrlstringURL to present to the user for authentication

Status Codes: 200 Success, 429 Rate limit exceeded (10 req/min)

GET /auth/connect/status

Poll connection status.

Authentication: Public

Query Parameters: code (required). The connection code from the initiate response.

Response (pending):

{
"status": "pending"
}

Response (ready, returned once, then code is consumed):

{
"status": "ready",
"apiKey": "nava_live_abc123def456...",
"walletAddress": "0x1234567890123456789012345678901234567890"
}

The API key is returned exactly once. After the first successful "ready" response, subsequent polls return 410 Gone.

The provisioned API key has scopes: transactions:create:own, transactions:approve:own, transactions:read:own.

Status Codes: 200 Success, 404 Code not found, 410 Expired or consumed, 429 Rate limit (30 req/min)

POST /auth/connect/approve

Approve a connection and provision an API key.

Authentication: JWT

Request Body:

{
"code": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
}

Response:

{
"success": true
}

Status Codes: 200 Approved, 400 Not in pending state, 401 JWT required, 404 Not found, 410 Expired, 429 Rate limit (5 req/min)

MCP OAuth 2.1

MCP Endpoint

POST|GET|DELETE /mcp

MCP Streamable HTTP transport endpoint.

Authentication: OAuth 2.1 Bearer token (preferred) or API key (legacy)

  • POST: Send MCP messages (initialize, tool calls, etc.)
  • GET: Open SSE stream for server notifications
  • DELETE: Terminate an MCP session

Headers:

  • Authorization: Bearer <access_token> (OAuth 2.1, preferred)
  • x-api-key: <api-key> (legacy fallback)
  • Mcp-Session-Id: <session-id> (required after initialization)
  • Accept: application/json, text/event-stream

Available MCP Tools:

ToolDescription
requestVerificationSubmit a blockchain transaction for verification
checkVerificationStatusCheck the verification status of a submitted transaction

OAuth 2.1 Discovery

GET /.well-known/oauth-protected-resource

OAuth Protected Resource Metadata (RFC 9728).

Authentication: Public

Response:

{
"resource": "https://internal.navalabs.dev/api/mcp",
"authorization_servers": ["https://internal.navalabs.dev/api"],
"scopes_supported": [
"transactions:create:own",
"transactions:approve:own",
"transactions:read:own"
],
"resource_name": "Nava MCP Server"
}

GET /.well-known/oauth-authorization-server

OAuth Authorization Server Metadata (RFC 8414).

Authentication: Public

OAuth 2.1 Client Registration

POST /oauth/register

Dynamic Client Registration (RFC 7591).

Authentication: Public

Request Body:

{
"redirect_uris": ["http://127.0.0.1:3000/callback"],
"client_name": "My MCP Client",
"grant_types": ["authorization_code", "refresh_token"],
"token_endpoint_auth_method": "client_secret_post"
}

Response (201):

{
"client_id": "nava_mcp_a1b2c3d4e5f6...",
"client_secret": "raw-secret-shown-once",
"client_id_issued_at": 1700000000,
"redirect_uris": ["http://127.0.0.1:3000/callback"],
"client_name": "My MCP Client",
"grant_types": ["authorization_code", "refresh_token"],
"token_endpoint_auth_method": "client_secret_post"
}

OAuth 2.1 Authorization Flow

GET /oauth/authorize

OAuth Authorization Endpoint. Redirects to the Nava UI consent page.

Query Parameters: response_type (must be "code"), client_id, redirect_uri, code_challenge, code_challenge_method, state, scope, resource

GET /oauth/session-info

Get OAuth session details for the consent page.

Query Parameters: session (required)

POST /oauth/approve

Approve an OAuth session after the user authenticates via SIWE.

Authentication: JWT

Request Body:

{
"sessionId": "uuid-session-id"
}

Response:

{
"redirectUrl": "http://127.0.0.1:3000/callback?code=AUTH_CODE&state=STATE"
}

OAuth 2.1 Token Exchange

POST /oauth/token

OAuth Token Endpoint. Supports authorization_code and refresh_token grants.

Response:

{
"access_token": "jwt-access-token",
"token_type": "bearer",
"expires_in": 900,
"refresh_token": "new-refresh-token",
"scope": "transactions:create:own transactions:approve:own transactions:read:own"
}

Access tokens are JWTs with a 15-minute expiry. Refresh tokens rotate on each use with a 30-day expiry.