Authentication
OAuth 2.0 authorization code flow. PKCE is supported but not required.
The flow
Standard authorization code. Your application sends the person to our authorization endpoint, they approve and choose a TallyPrime connection, and you exchange the returned code for tokens.
1. Send them to authorize
http://localhost:4173/api/v1/oauth/authorize
?client_id=YOUR_CLIENT_ID
&redirect_uri=https://your-platform.example/callback
&response_type=code
&scope=tally.read%20tally.write%20connection.read
&state=RANDOM_STRINGredirect_uri must match one you registered on the application, exactly — no wildcards and no prefixes. That exactness is what stops a crafted link from sending an authorization code somewhere else.2. Exchange the code
curl -X POST http://localhost:4173/api/v1/oauth/token \
-u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" \
-d "grant_type=authorization_code" \
-d "code=THE_CODE" \
-d "redirect_uri=https://your-platform.example/callback"{
"access_token": "…",
"refresh_token": "…",
"token_type": "Bearer",
"expires_in": 2592000,
"scope": "tally.read tally.write connection.read",
"connection_name": "ABC Traders",
"company_name": "ABC TRADERS PVT LTD"
}connection_name and company_name ride along so you can label the saved connection without a second call.
3. Call the API
Authorization: Bearer YOUR_ACCESS_TOKENRefreshing
curl -X POST http://localhost:4173/api/v1/oauth/token \
-u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" \
-d "grant_type=refresh_token" \
-d "refresh_token=YOUR_REFRESH_TOKEN"The refresh token is not rotated
PKCE
Optional, enforced when used: code_challenge + code_challenge_method=S256 on authorize, code_verifier on the token request.
Revoking
curl -X POST http://localhost:4173/api/v1/oauth/revoke \
-u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" \
-d "token=THE_ACCESS_OR_REFRESH_TOKEN"Always answers 200, whether or not the token existed — so it cannot be used to discover which tokens are live.
Testing a connection
GET /api/v1/oauth/userinfo confirms a token works and names the connection and company behind it. It is what a connector's “Test connection” button should call.
Something missing on this page? Tell us and we will fix it.