VU.CITY Developer Hub

Authentication

Get an access token and start making authenticated requests.

The Build API uses OAuth 2.0's client credentials grant. This is the standard way for one service to authenticate to another with no human in the loop — there's no login page, no browser redirect, and no user consent screen. If you've only used OAuth for "Sign in with X" buttons before, this is the same protocol used for a much simpler job: proving that your server is allowed to call our API.

At a high level:

  1. You exchange a client ID and client secret for a short-lived access token.
  2. You send that access token with every API request.
  3. When it expires, you request a new one the same way.

There's no separate login step and no refresh token — getting a new access token is the refresh mechanism.

1. Get a client ID and secret

VU.CITY provisions a client ID and client secret for you, along with the scopes your client is allowed to request. Treat the client secret like a password:

Keep your client secret server-side

The API has no CORS support, so it can't be called from browser JavaScript anyway — but the same rule applies to your own code: never embed the client secret in a mobile app, a single-page app, or any code that ships to a user's device. Store it as a server-side secret.

2. Request an access token

Exchange your credentials for an access token at the token endpoint:

POST https://build.vu.city/oauth/token

The request must be application/x-www-form-urlencoded with grant_type=client_credentials. You can send your client ID and secret either as HTTP Basic auth, or as client_id/client_secret fields in the form body — pick whichever is more convenient for your HTTP client.

HTTP Basic auth:

curl -X POST https://build.vu.city/oauth/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d grant_type=client_credentials

Credentials in the form body:

curl -X POST https://build.vu.city/oauth/token \
  -d grant_type=client_credentials \
  -d client_id=$CLIENT_ID \
  -d client_secret=$CLIENT_SECRET

A successful response looks like this:

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "volume:read"
}

expires_in is the token's lifetime in seconds. By default you're granted every scope your client is allowed to request; to ask for a smaller set instead, add a space-separated scope parameter to the request (e.g. -d scope=volume:read). Asking for a scope you don't hold returns an invalid_scope error rather than silently dropping it.

3. Call the API with your access token

Send the access token as a bearer token in the Authorization header of every request:

curl https://build.vu.city/v0/volumes \
  -H "Authorization: Bearer $ACCESS_TOKEN"

That's the whole flow — see the API reference for the endpoints available to you.

Token lifetime

Access tokens are only valid for expires_in seconds (see the response above). There are no refresh tokens in the client credentials grant: when a token expires, request a new one the same way you got the first one, using your client ID and secret again. Most OAuth client libraries do this automatically — they cache the token and re-request it once it's close to expiring.

Revoking a client

If VU.CITY revokes your client, no new tokens can be issued, but any token already issued keeps working until it expires. Keep this in mind if you ever need access cut off immediately.

Scopes

An access token carries one or more scopes, each granting access to a specific capability. Every endpoint in the API reference documents which scope it requires.

ScopeGrants
volume:readList and read VU.CITY Drive volumes

Calling an endpoint without the scope it requires returns a 403 with insufficient_scope, even if your access token is otherwise valid — see Errors below.

Errors

SituationResponse
Wrong client ID or secret401 with { "error": "invalid_client" }
Grant type other than client_credentials400 with { "error": "unsupported_grant_type" }
Requested a scope your client isn't allowed400 with { "error": "invalid_scope" }
Missing or malformed access token on an API request401 Unauthorized
Valid token, but missing the required scope403 with error: "insufficient_scope"

Service discovery

If your HTTP client or library supports OpenID Connect discovery, you can point it at:

  • https://build.vu.city/.well-known/openid-configuration — issuer metadata, including the token endpoint and supported scopes.
  • https://build.vu.city/.well-known/jwks.json — the public key used to sign access tokens, if you need to verify them yourself.

On this page