Authentication

OAuth2 client credentials flow for the Further AI API

The Further AI API uses OAuth2 Client Credentials for authentication. You exchange a client ID and secret for a short-lived access token, then pass that token as a Bearer header on every subsequent request.

Overview

┌─────────────┐ ┌──────────────────┐
│ Your App │ │ Further AI API │
└──────┬──────┘ └────────┬─────────┘
│ │
│ POST /oauth2/access_token
│ { client_id, client_secret }
│─────────────────────────▶│
│ │
│ { access_token, ... } │
│◀─────────────────────────│
│ │
│ GET /executions/... │
│ Authorization: Bearer <token>
│─────────────────────────▶│
│ │

Token Endpoint

FieldValue
URLhttps://api.further.ai/api/v1/oauth2/access_token
MethodPOST
Content-Typeapplication/json

Request Body

ParameterTypeRequiredDescription
client_idstringYesYour API client identifier
client_secretstringYesYour API client secret

Response

A successful response returns:

1{
2 "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
3 "token_type": "bearer",
4 "expires_in": 3600
5}
FieldDescription
access_tokenThe JWT bearer token to use in API requests
token_typeAlways "bearer"
expires_inToken lifetime in seconds (3600 = 60 minutes)

Token Expiry

Access tokens expire after 60 minutes. Your application must request a new token before the current one expires. There is no refresh-token flow; simply call the token endpoint again with your credentials.

Examples

cURL

$# Generate an access token
$curl -X POST https://api.further.ai/api/v1/oauth2/access_token \
> -H "Content-Type: application/json" \
> -d '{
> "client_id": "YOUR_CLIENT_ID",
> "client_secret": "YOUR_CLIENT_SECRET"
> }'

Python

1import requests
2
3TOKEN_URL = "https://api.further.ai/api/v1/oauth2/access_token"
4
5def get_access_token(client_id: str, client_secret: str) -> str:
6 """Exchange client credentials for an access token."""
7 response = requests.post(TOKEN_URL, json={
8 "client_id": client_id,
9 "client_secret": client_secret
10 })
11 response.raise_for_status()
12 return response.json()["access_token"]
13
14
15# Usage
16access_token = get_access_token("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET")

Python with Automatic Refresh

For long-running applications, implement token caching with automatic refresh:

1import time
2import requests
3
4TOKEN_URL = "https://api.further.ai/api/v1/oauth2/access_token"
5
6class FurtherAIAuth:
7 """Manages Further AI API authentication with automatic token refresh."""
8
9 def __init__(self, client_id: str, client_secret: str):
10 self.client_id = client_id
11 self.client_secret = client_secret
12 self._token = None
13 self._expires_at = 0
14
15 def get_token(self) -> str:
16 """Return a valid access token, refreshing if needed."""
17 # Refresh 5 minutes before expiry
18 if self._token is None or time.time() > (self._expires_at - 300):
19 self._refresh()
20 return self._token
21
22 def _refresh(self):
23 response = requests.post(TOKEN_URL, json={
24 "client_id": self.client_id,
25 "client_secret": self.client_secret
26 })
27 response.raise_for_status()
28 data = response.json()
29 self._token = data["access_token"]
30 self._expires_at = time.time() + data.get("expires_in", 3600)
31
32 def get_headers(self) -> dict:
33 """Return Authorization headers ready for requests."""
34 return {"Authorization": f"Bearer {self.get_token()}"}
35
36
37# Usage
38auth = FurtherAIAuth("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET")
39
40# Headers are always fresh
41response = requests.get(
42 "https://api.further.ai/api/v1/workflow-builder/workflows/WF_ID/executions/EX_ID",
43 headers=auth.get_headers()
44)

Using the Bearer Token

Once you have an access token, include it in the Authorization header of every API request:

Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
1headers = {
2 "Authorization": f"Bearer {access_token}"
3}
4
5response = requests.get(
6 f"https://api.further.ai/api/v1/workflow-builder/workflows/{workflow_id}/executions/{execution_id}",
7 headers=headers
8)

Error Responses

Status CodeDescription
401 UnauthorizedInvalid or expired token. Generate a new one.
422 Unprocessable EntityMissing or malformed client_id / client_secret.

Security Best Practices

  • Never expose your client_secret in client-side code or public repositories.
  • Store credentials in environment variables or a secrets manager.
  • Rotate your credentials periodically and immediately if you suspect a compromise.
  • Always use HTTPS for all API communication.