nsindocs Search the docs⌘K
  1. Docs
  2. API reference
  3. SSO

Exchange a code, or refresh a token

posthttps://api.nsin.ir/oauth/token

No authentication.

Accepts application/x-www-form-urlencoded (the OAuth default) and JSON. A confidential client authenticates with client_secret_post or HTTP Basic; a public client sends no secret and is protected by PKCE alone.

grant_type=authorization_code — send code, redirect_uri, client_id and code_verifier. The code is single-use and lives five minutes. A code that never existed, has expired or has already been redeemed all answer the same invalid_grant.

grant_type=refresh_token — send refresh_token and client_id. Refresh tokens rotate: the response carries a new one and the presented token is burnt. Presenting a burnt token is treated as a leak and revokes every token of that login. scope may be sent to narrow the new token; it can never widen.

A refresh_token is only issued when the offline_access scope was granted. Rate limited to 60 requests per minute per IP and 600 per minute per client_id.

Request body

Content type: application/x-www-form-urlencoded · required

  • grant_typestringrequired
    One of: "authorization_code" "refresh_token"
  • client_idstringrequired
  • client_secretstring

    Confidential clients only, and only when not using HTTP Basic. A public client never sends one.

  • codestring

    authorization_code only — the value from the redirect.

  • redirect_uristring

    authorization_code only — must equal the one the code was issued for.

  • code_verifierstring

    authorization_code only. The PKCE verifier, 43–128 characters from [A-Za-z0-9._~-], whose SHA-256 produced the code_challenge.

  • refresh_tokenstring

    refresh_token only.

  • scopestring

    refresh_token only, and optional: narrows the new token. It can never widen — asking for more than was granted is invalid_scope.

Content type: application/json · required

  • grant_typestringrequired
    One of: "authorization_code" "refresh_token"
  • client_idstringrequired
  • client_secretstring

    Confidential clients only, and only when not using HTTP Basic. A public client never sends one.

  • codestring

    authorization_code only — the value from the redirect.

  • redirect_uristring

    authorization_code only — must equal the one the code was issued for.

  • code_verifierstring

    authorization_code only. The PKCE verifier, 43–128 characters from [A-Za-z0-9._~-], whose SHA-256 produced the code_challenge.

  • refresh_tokenstring

    refresh_token only.

  • scopestring

    refresh_token only, and optional: narrows the new token. It can never widen — asking for more than was granted is invalid_scope.

Responses

200A fresh token set.

Content type: application/json

  • access_tokenstring

    RS256 JWT. Verify it against the JWKS.

  • token_typestring
    One of: "Bearer"
  • expires_ininteger

    Access token lifetime in seconds.

  • refresh_tokenstring

    Present only when offline_access was granted.

  • id_tokenstring

    RS256 JWT carrying the identity claims the scopes allow.

  • scopestring

    The scopes actually granted, space-separated.

json
{
  "access_token": "string",
  "token_type": "Bearer",
  "expires_in": 0,
  "refresh_token": "string",
  "id_token": "string",
  "scope": "string"
}
400invalid_request, unsupported_grant_type, invalid_grant (unknown, expired, already-used or mismatched code or refresh token — deliberately indistinguishable), invalid_scope, or unauthorized_client for a client that has been switched off.

Content type: application/json

  • errorstringrequired

    The machine-readable code.

  • error_descriptionstring

    A human-readable explanation. Never match on this.

json
{
  "error": "invalid_grant",
  "error_description": "authorization code is invalid or expired"
}
401invalid_client — the client id is unknown or the secret is wrong. Carries WWW-Authenticate: Basic when Basic auth was attempted.

Content type: application/json

  • errorstringrequired

    The machine-readable code.

  • error_descriptionstring

    A human-readable explanation. Never match on this.

json
{
  "error": "invalid_grant",
  "error_description": "authorization code is invalid or expired"
}
429Too many token requests.

Content type: application/json

  • errorstringrequired

    Human-readable description of what went wrong.

json
{
  "error": "slow_down"
}

Example request

bash
curl -X POST "https://api.nsin.ir/oauth/token" \
  -H "Authorization: Bearer $NSIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "grant_type": "authorization_code",
  "client_id": "string",
  "client_secret": "string",
  "code": "string",
  "redirect_uri": "string",
  "code_verifier": "string",
  "refresh_token": "string",
  "scope": "string"
}'
esc