Authentication
Teloring uses OAuth 2.0 client credentials. You hold a long-lived client id and secret; you exchange them for a short-lived access token; you send that token on every request.
client id + secret ──POST /v1/oauth/token──▶ access token (1 hour)
│
Authorization: Bearer ────┘
The split is the point. A leaked access token expires by itself within the hour. A leaked secret is revoked in one click, without you redeploying anything.
Creating a credential
Settings → API → New credential. You choose four things:
| Name | For you. It shows up in the audit log next to everything this credential does, so name it after the integration, not after a person. |
| Expiration | A date, or unlimited. A date is worth setting for anything temporary — a migration script, a contractor's integration. |
| Scopes | Which feature areas it may reach. See Scopes. |
| SSO settings | Only if you ticked the sso scope: which agents it may sign in as, and which sites may embed the session. |
You get back a client id (tlc_…, visible forever) and a client secret
(tls_…, shown once).
It is stored only as a bcrypt hash. Nobody — not an Owner, not Teloring support — can retrieve it afterwards. Lost it? Revoke the credential and create another.
Getting a token
POST /v1/oauth/token accepts your credentials three ways. Use whichever your
HTTP client makes easiest; they are equivalent.
JSON body
curl -X POST https://api.teloring.com/v1/oauth/token \
-H "Content-Type: application/json" \
-d '{"client_id": "tlc_…", "client_secret": "tls_…"}'
Form-encoded (what most OAuth libraries send)
curl -X POST https://api.teloring.com/v1/oauth/token \
-d grant_type=client_credentials \
-d client_id=tlc_… \
-d client_secret=tls_…
HTTP Basic (RFC 6749 §2.3.1)
curl -X POST https://api.teloring.com/v1/oauth/token \
-u "tlc_…:tls_…" \
-d grant_type=client_credentials
If both a Basic header and body parameters are present, the header wins — a body parameter cannot downgrade it.
Cache the token
One token per hour is the expected pattern. The token endpoint is rate limited to 20 requests per minute per IP, and ten consecutive failures against one client id lock that client out for fifteen minutes.
A minimal client, in the shape most people end up writing:
import time, requests
class Teloring:
BASE = "https://api.teloring.com/v1"
def __init__(self, client_id, client_secret):
self._id, self._secret = client_id, client_secret
self._token, self._expires_at = None, 0
def _auth_header(self):
# Refresh a minute early so a request never races the expiry.
if not self._token or time.time() > self._expires_at - 60:
response = requests.post(
f"{self.BASE}/oauth/token",
json={"client_id": self._id, "client_secret": self._secret},
timeout=10,
)
response.raise_for_status()
payload = response.json()
self._token = payload["access_token"]
self._expires_at = time.time() + payload["expires_in"]
return {"Authorization": f"Bearer {self._token}"}
def get(self, path, **params):
response = requests.get(f"{self.BASE}{path}", headers=self._auth_header(),
params=params, timeout=30)
if response.status_code == 401: # revoked or edited mid-flight
self._token = None
response = requests.get(f"{self.BASE}{path}", headers=self._auth_header(),
params=params, timeout=30)
response.raise_for_status()
return response.json()
The 401 retry matters more than it looks. Editing a credential's scopes, or
revoking it, invalidates outstanding tokens immediately — so a token can stop
working before its stated expiry, and the correct response is to fetch a new one
once, not to crash.
Using the token
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…
Not sure what a token can do? GET /v1/oauth/introspect tells you the account,
the credential, and exactly which scopes it holds. It is the fastest way to
explain a surprising 403.