Skip to content

Authentication

Overview

The Pontotel API uses Bearer Token Authentication (JWT) to authenticate requests.

Authentication Flow

  1. Send credentials to the /login/ endpoint
  2. Receive access_token in the response
  3. Include token in the Authorization: Bearer {token} header
  4. Token expires in 1 hour

Login Endpoint

POST /api/v4/login/

Request

JSON
1
2
3
4
{
  "username": "your_username",
  "password": "your_password"
}

Response (200 OK)

JSON
{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "user": {
    "id": 123,
    "username": "your_username",
    "email": "your@email.com"
  }
}

Code Examples

Python
import requests
from datetime import datetime, timedelta

class PontotelAuth:
    def __init__(self, username, password, base_url):
        self.username = username
        self.password = password
        self.base_url = base_url
        self.token = None
        self.token_expires_at = None

    def login(self):
        """Performs login and obtains token"""
        url = f"{self.base_url}/login/"
        payload = {
            "username": self.username,
            "password": self.password
        }

        response = requests.post(url, json=payload)
        response.raise_for_status()

        data = response.json()
        self.token = data["access_token"]
        self.token_expires_at = datetime.now() + timedelta(seconds=data["expires_in"])

        return self.token

    def get_token(self):
        """Returns valid token, renewing if necessary"""
        if not self.token or datetime.now() >= self.token_expires_at:
            self.login()
        return self.token

    def get_headers(self):
        """Returns headers with authentication"""
        return {
            "Authorization": f"Bearer {self.get_token()}",
            "Content-Type": "application/json"
        }

# Usage
auth = PontotelAuth(
    username="your_username",
    password="your_password",
    base_url="https://apis.pontotel.com.br/pontotel/api/v4"
)

# Make requests
headers = auth.get_headers()
response = requests.get(
    "https://apis.pontotel.com.br/pontotel/api/v4/usuarios/",
    headers=headers
)
JavaScript
class PontotelAuth {
  constructor(username, password, baseUrl) {
    this.username = username;
    this.password = password;
    this.baseUrl = baseUrl;
    this.token = null;
    this.tokenExpiresAt = null;
  }

  async login() {
    const url = `${this.baseUrl}/login/`;
    const response = await fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        username: this.username,
        password: this.password
      })
    });

    if (!response.ok) {
      throw new Error(`Login failed: ${response.status}`);
    }

    const data = await response.json();
    this.token = data.access_token;
    this.tokenExpiresAt = Date.now() + (data.expires_in * 1000);

    return this.token;
  }

  async getToken() {
    if (!this.token || Date.now() >= this.tokenExpiresAt) {
      await this.login();
    }
    return this.token;
  }

  async getHeaders() {
    const token = await this.getToken();
    return {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    };
  }
}

// Usage
const auth = new PontotelAuth(
  'your_username',
  'your_password',
  'https://apis.pontotel.com.br/pontotel/api/v4'
);

// Make requests
const headers = await auth.getHeaders();
const response = await fetch(
  'https://apis.pontotel.com.br/pontotel/api/v4/usuarios/',
  { headers }
);
Bash
# 1. Login
curl -X POST "https://apis.pontotel.com.br/pontotel/api/v4/login/" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "your_username",
    "password": "your_password"
  }' \
  | jq -r '.access_token' > token.txt

# 2. Use token
TOKEN=$(cat token.txt)

curl -X GET "https://apis.pontotel.com.br/pontotel/api/v4/usuarios/" \
  -H "Authorization: Bearer $TOKEN"

Security

Important Practices

  • Never share credentials or tokens
  • Store tokens in environment variables or secret managers
  • Rotate credentials regularly
  • Use HTTPS always (mandatory)
  • Do not commit tokens to Git

Secure Storage

Python
# .env
PONTOTEL_USERNAME=your_username
PONTOTEL_PASSWORD=your_password

# code
from dotenv import load_dotenv
import os

load_dotenv()

auth = PontotelAuth(
    username=os.getenv("PONTOTEL_USERNAME"),
    password=os.getenv("PONTOTEL_PASSWORD"),
    base_url="https://apis.pontotel.com.br/pontotel/api/v4"
)
JavaScript
// .env
PONTOTEL_USERNAME=your_username
PONTOTEL_PASSWORD=your_password

// code
require('dotenv').config();

const auth = new PontotelAuth(
  process.env.PONTOTEL_USERNAME,
  process.env.PONTOTEL_PASSWORD,
  'https://apis.pontotel.com.br/pontotel/api/v4'
);

Expiration and Renewal

  • Tokens expire in 1 hour (3600 seconds)
  • Implement automatic renewal logic
  • Handle 401 Unauthorized errors by re-authenticating

Retry Logic Example

Python
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

def requests_retry_session(retries=3):
    session = requests.Session()
    retry = Retry(
        total=retries,
        read=retries,
        connect=retries,
        backoff_factor=0.3,
        status_forcelist=(401, 500, 502, 504),
    )
    adapter = HTTPAdapter(max_retries=retry)
    session.mount('http://', adapter)
    session.mount('https://', adapter)
    return session

# Usage
session = requests_retry_session()
response = session.get(url, headers=headers)

Common Errors

Code Error Solution
400 Bad Request Check payload format
401 Unauthorized Invalid credentials or expired token
403 Forbidden No permission for the resource
429 Too Many Requests Wait for rate limit

Next Steps