Home/
Developer Portal

Authentication

Sergio uses two authentication methods depending on the API surface. The main API uses JWT bearer tokens, while the Zapier API uses API key authentication.

JWT Authentication (Main API)

The main Sergio API uses JSON Web Tokens (JWT) for authentication. Tokens are obtained by exchanging valid credentials and included in the Authorization header.

Auth Flow

POST /auth/login
Receive JWT + Refresh Token
Use Bearer Token in Headers
Refresh Before Expiry

Login Request

auth.ts
typescript
const response = await fetch('https://api.sergio.app/v1/auth/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    email: 'admin@yourcompany.com',
    password: 'your-password',
  }),
});

const { token, refresh_token, expires_at } = await response.json();

// Use the token in subsequent requests
const jobs = await fetch('https://api.sergio.app/v1/jobs', {
  headers: { 'Authorization': `Bearer ${token}` },
});
Auth.kt
kotlin
val response = httpClient.post("https://api.sergio.app/v1/auth/login") {
    contentType(ContentType.Application.Json)
    setBody(LoginRequest(
        email = "admin@yourcompany.com",
        password = "your-password"
    ))
}

val auth = response.body<AuthResponse>()

// Use the token in subsequent requests
val jobs = httpClient.get("https://api.sergio.app/v1/jobs") {
    bearerAuth(auth.token)
}
Auth.swift
swift
var request = URLRequest(url: URL(string: "https://api.sergio.app/v1/auth/login")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONEncoder().encode([
    "email": "admin@yourcompany.com",
    "password": "your-password"
])

let (data, _) = try await URLSession.shared.data(for: request)
let auth = try JSONDecoder().decode(AuthResponse.self, from: data)

// Use the token in subsequent requests
var jobsRequest = URLRequest(url: URL(string: "https://api.sergio.app/v1/jobs")!)
jobsRequest.setValue("Bearer \(auth.token)", forHTTPHeaderField: "Authorization")

Token Refresh

refresh.ts
typescript
const refreshResponse = await fetch('https://api.sergio.app/v1/auth/refresh', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ refresh_token }),
});

const { token: newToken, expires_at: newExpiry } = await refreshResponse.json();

API Key Authentication (Zapier API)

The Zapier API uses static API keys passed via the X-API-Key header. API keys are generated from your Sergio dashboard and are scoped to your company.

terminal
bash
curl -X GET https://api.sergio.app/zapier/v1/triggers/new-job \
  -H "X-API-Key: sk_live_your_api_key_here" \
  -H "Content-Type: application/json"

Rate Limiting

The API enforces rate limits per API key/token. When exceeded, you'll receive a 429 Too Many Requests response with a Retry-After header.

EndpointRate Limit
Authentication10 req/min
Read operations120 req/min
Write operations60 req/min
Webhook registration10 req/min
Bulk operations10 req/min

Security Best Practices

Store secrets securely

Use environment variables or a secrets manager. Never hardcode tokens or API keys.

Rotate keys regularly

Generate new API keys periodically. Revoke old keys from the dashboard immediately.

Use HTTPS only

All API requests must use HTTPS. HTTP requests will be rejected.

Validate webhook signatures

Always verify the HMAC-SHA256 signature on incoming webhooks before processing.

Implement token refresh

JWT tokens expire after 1 hour. Use refresh tokens to get new access tokens.

Scope API keys narrowly

Request only the permissions you need. Avoid using admin-level keys for integrations.