Skip to content

Authentication ​

Both the API and the MCP server use OAuth 2.0 with PKCE (S256) and dynamic client registration. The authorization server is the same host as the product.

text
https://app.intangia.co

A token is bound to one resource. Ask for the resource you will call:

SurfaceResource
APIhttps://app.intangia.co/api/v1
MCPhttps://app.intangia.co/mcp

Send the access token as Authorization: Bearer. Access tokens last one hour (expires_in is 3600). Refresh tokens last 30 days.

Scopes ​

ScopeWhat It Allows
intangia:readKeywords, projects, signals, opportunities, and assessments
projects:writeCreate and update projects, run setup, and create or list reports
analyses:runStart scoring

The token response lists the scopes that were granted, space-separated.

Discovery ​

Clients that speak MCP OAuth can discover the server and skip the manual steps below.

text
GET /.well-known/oauth-authorization-server
GET /.well-known/oauth-protected-resource/api/v1
GET /.well-known/oauth-protected-resource/mcp

The authorization server document names these endpoints:

EndpointPath
Authorize/oauth/authorize
Token/oauth/token
Register/oauth/register
Revoke/oauth/revoke

Supported grant types are authorization_code and refresh_token. The only code challenge method is S256. The token endpoint accepts public clients (token_endpoint_auth_method is none).

Register a Client ​

POST /oauth/register with JSON.

json
{
  "client_name": "Example",
  "redirect_uris": ["http://127.0.0.1:8787/callback"]
}

Redirect URIs must be https, or loopback HTTP (localhost, 127.0.0.1, [::1]). A 201 response includes client_id. There is no client secret.

Too many registrations from one address return 429 with error slow_down.

Authorize ​

Send the user to /oauth/authorize.

ParameterValue
response_typecode
client_idFrom registration
redirect_uriOne registered URI
code_challengeBase64url SHA-256 of the verifier
code_challenge_methodS256
resourceThe API or MCP resource
scopeSpace-separated scopes
stateA value you check on return

The user signs in and approves. The redirect carries code and state. Authorization codes last 60 seconds and can be used once.

Exchange the Code ​

POST /oauth/token with Content-Type: application/x-www-form-urlencoded.

text
grant_type=authorization_code
&code=...
&client_id=...
&redirect_uri=...
&code_verifier=...
&resource=https://app.intangia.co/api/v1

resource must be exactly the API or MCP resource. A mismatch returns invalid_target.

json
{
  "access_token": "...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "...",
  "scope": "intangia:read projects:write analyses:run"
}

The response is cache-control: no-store.

Refresh with grant_type=refresh_token, refresh_token, and client_id. You may send resource again. Each refresh rotates the refresh token.

Revoke ​

POST /oauth/revoke with the token to cancel. Revoking is how a user disconnects a client.

Call the API ​

bash
curl "https://app.intangia.co/api/v1/projects" \
  -H "Authorization: Bearer $TOKEN"

$TOKEN must have been issued for https://app.intangia.co/api/v1.

Errors ​

OAuth errors use error and error_description.

StatuserrorWhen
400invalid_client_metadataRegistration body is not JSON, or no acceptable redirect URI
400invalid_targetresource is not the API or MCP resource
400invalid_grantCode or refresh token is missing, expired, reused, or PKCE fails
400unsupported_grant_typegrant_type is not authorization_code or refresh_token
429slow_downToo many registrations

API and MCP HTTP errors use a different body. See the API overview.

Actionable insights for better R&D and strategy decisions.