Introduction
API tokens allow you to integrate REST Lens with your CI/CD pipelines (GitHub Actions, GitLab CI, Jenkins, etc.) to automatically validate OpenAPI specifications on every commit.
Key Benefits
- Automated validation: Check API specs on every push
- Project-scoped security: Each token is tied to a specific project
- Revocable: Instantly revoke access if a token is compromised
- Audit trail: See when each token was last used
Creating API Tokens
Step-by-Step Guide
- Navigate to your project settings page:
/projects/[org]/[project]/settings - Scroll to the "API Tokens" section
- Click "Create New Token"
- Enter a descriptive name (e.g., "GitHub Actions - Main Branch")
- (Optional) Set an expiration date
- Click "Create Token"
- IMPORTANT: Copy the token immediately - it will only be shown once!
Token Format
All REST Lens API tokens follow this format:
rl_[43 random characters]
Example: rl_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v
Token Properties
- Name: Human-readable identifier (e.g., "Jenkins Prod Pipeline")
- Token Prefix: First 11 characters for identification (e.g.,
rl_a1b2c3d4) - Created: Timestamp when token was created
- Last Used: Timestamp of most recent API call (updated on each use)
- Expires: Optional expiration date
Using API Tokens
Authentication
Include the token in the Authorization header using Bearer authentication:
Authorization: Bearer rl_your_token_here
Supported Endpoints
Currently, API tokens can be used for:
- Upload Specification:
POST /api/projects/[org]/[slug]/specifications
Rate Limits
API token requests are subject to the same rate limits as authenticated user requests:
- Specification uploads: 10 requests per minute per project
CI/CD Integration Examples
GitHub Actions
1. Store Token as Secret
- Go to your GitHub repository → Settings → Secrets and variables → Actions
- Click "New repository secret"
- Name:
RESTLENS_API_TOKEN - Value: Your token (e.g.,
rl_...) - Click "Add secret"
2. Create Workflow
Create .github/workflows/validate-api.yml:
name: Validate OpenAPI Spec
on:
push:
branches: [main]
paths:
- 'openapi.yaml'
pull_request:
branches: [main]
paths:
- 'openapi.yaml'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Upload spec to REST Lens
run: |
curl -X POST \
https://restlens.com/api/projects/my-org/my-project/specifications \
-H "Authorization: Bearer ${{ secrets.RESTLENS_API_TOKEN }}" \
-H "Content-Type: application/x-yaml" \
-H "X-Spec-Tag: ${{ github.sha }}" \
--data-binary @openapi.yaml
- name: Check validation status
run: echo "Check results at https://restlens.com/projects/my-org/my-project"
GitLab CI
1. Store Token as Variable
- Go to your GitLab project → Settings → CI/CD → Variables
- Click "Add variable"
- Key:
RESTLENS_API_TOKEN - Value: Your token
- Check "Mask variable" and "Protect variable"
- Click "Add variable"
2. Create Pipeline
Create or update .gitlab-ci.yml:
stages:
- validate
validate-api:
stage: validate
image: curlimages/curl:latest
only:
changes:
- openapi.yaml
script:
- |
curl -X POST \
https://restlens.com/api/projects/my-org/my-project/specifications \
-H "Authorization: Bearer ${RESTLENS_API_TOKEN}" \
-H "Content-Type: application/x-yaml" \
-H "X-Spec-Tag: ${CI_COMMIT_SHA}" \
--data-binary @openapi.yaml
- echo "View results at https://restlens.com/projects/my-org/my-project"
Jenkins
1. Add Credentials
- Go to Jenkins → Manage Jenkins → Credentials
- Select your domain → "Add Credentials"
- Kind: "Secret text"
- Secret: Your token
- ID:
restlens-api-token - Description: "REST Lens API Token"
- Click "Create"
2. Create Pipeline
Create or update Jenkinsfile:
pipeline {
agent any
environment {
RESTLENS_TOKEN = credentials('restlens-api-token')
}
stages {
stage('Validate API Spec') {
when {
changeset "openapi.yaml"
}
steps {
script {
sh '''
curl -X POST \
https://restlens.com/api/projects/my-org/my-project/specifications \
-H "Authorization: Bearer ${RESTLENS_TOKEN}" \
-H "Content-Type: application/x-yaml" \
-H "X-Spec-Tag: ${GIT_COMMIT}" \
--data-binary @openapi.yaml
'''
echo "View results at https://restlens.com/projects/my-org/my-project"
}
}
}
}
}
Generic cURL Example
#!/bin/bash
# Upload OpenAPI specification to REST Lens
API_TOKEN="rl_your_token_here"
ORG_SLUG="my-org"
PROJECT_SLUG="my-project"
SPEC_FILE="openapi.yaml"
TAG="${CI_COMMIT_SHA:-local-dev}"
curl -X POST \
"https://restlens.com/api/projects/${ORG_SLUG}/${PROJECT_SLUG}/specifications" \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/x-yaml" \
-H "X-Spec-Tag: ${TAG}" \
--data-binary "@${SPEC_FILE}" \
-w "\nHTTP Status: %{http_code}\n"
API Reference
Upload Specification
Upload a new OpenAPI specification version for evaluation.
Endpoint: POST /api/projects/[org]/[slug]/specifications
Authentication: Bearer token in Authorization header
Headers:
Authorization: Bearer rl_...(required)Content-Type(required, see formats below)X-Spec-Tag(optional, for version tagging)
Body Formats:
1. JSON (application/json)
curl -X POST https://restlens.com/api/projects/my-org/my-project/specifications \
-H "Authorization: Bearer rl_your_token" \
-H "Content-Type: application/json" \
-d '{
"spec": {
"openapi": "3.0.0",
"info": { "title": "My API", "version": "1.0.0" }
},
"tag": "v1.0.0"
}'
Or send the spec directly:
curl -X POST https://restlens.com/api/projects/my-org/my-project/specifications \
-H "Authorization: Bearer rl_your_token" \
-H "Content-Type: application/json" \
-d @openapi.json
2. YAML (text/yaml or application/x-yaml)
curl -X POST https://restlens.com/api/projects/my-org/my-project/specifications \
-H "Authorization: Bearer rl_your_token" \
-H "Content-Type: application/x-yaml" \
-H "X-Spec-Tag: v1.0.0" \
--data-binary @openapi.yaml
3. Multipart Form Data (multipart/form-data)
curl -X POST https://restlens.com/api/projects/my-org/my-project/specifications \
-H "Authorization: Bearer rl_your_token" \
-F "[email protected]" \
-F "tag=v1.0.0"
Response (201 Created):
{
"specification": {
"id": "1234567890123456789",
"projectId": "9876543210987654321",
"tag": "v1.0.0",
"createdAt": "2025-12-22T10:30:00Z"
}
}
Error Responses:
401 Unauthorized: Invalid or expired token404 Not Found: Project not found or token not authorized for this project413 Payload Too Large: Specification exceeds 50MB limit429 Too Many Requests: Rate limit exceeded
Best Practices
Security
- Never commit tokens to git: Always use environment variables or CI/CD secrets
- One token per system: Create separate tokens for each CI/CD pipeline
- Use descriptive names: Name tokens clearly (e.g., "GitHub Actions - Prod")
- Set expiration dates: Use expiring tokens for temporary access
- Rotate regularly: Periodically create new tokens and revoke old ones
- Monitor usage: Check "Last Used" timestamps to detect unused or compromised tokens
Configuration
# Good: Use environment variables
export RESTLENS_TOKEN="rl_..."
curl -H "Authorization: Bearer $RESTLENS_TOKEN" ...
# Bad: Hardcoded token
curl -H "Authorization: Bearer rl_a1b2c3..." ... # DON'T DO THIS
Version Tagging
Use meaningful tags to track specification versions:
# Good examples
-H "X-Spec-Tag: ${GIT_COMMIT_SHA}" # Git commit hash
-H "X-Spec-Tag: v1.2.3" # Semantic version
-H "X-Spec-Tag: build-${BUILD_NUMBER}" # CI build number
-H "X-Spec-Tag: 2025-12-22-prod" # Date + environment
# Bad examples
-H "X-Spec-Tag: latest" # Too generic
-H "X-Spec-Tag: test" # Not descriptive
Troubleshooting
401 Unauthorized
Cause: Token is invalid, expired, or missing
Solutions:
- Verify token is correctly copied (including
rl_prefix) - Check if token has expired
- Ensure token hasn't been revoked
- Verify
Authorization: Bearerformat is correct
# Correct format
Authorization: Bearer rl_a1b2c3d4e5...
# Wrong - missing "Bearer"
Authorization: rl_a1b2c3d4e5...
404 Not Found
Cause: Project path is incorrect or token isn't authorized for this project
Solutions:
- Verify organization slug and project slug in URL
- Ensure token was created for the correct project
- Check that project hasn't been deleted
# Correct URL structure
/api/projects/[org-slug]/[project-slug]/specifications
# Example
/api/projects/acme-corp/payment-api/specifications
413 Payload Too Large
Cause: Specification file exceeds 50MB limit
Solutions:
- Check file size:
ls -lh openapi.yaml - Remove unnecessary examples or descriptions
- Split into multiple smaller specifications if needed
# Check file size
$ ls -lh openapi.yaml
-rw-r--r-- 1 user staff 52M Dec 22 10:00 openapi.yaml
# This file is too large (52MB > 50MB)
429 Too Many Requests
Cause: Rate limit exceeded (10 uploads per minute)
Solutions:
- Add delay between uploads in CI scripts
- Avoid triggering multiple pipelines simultaneously
- Contact support for higher limits if needed
# Add delay if uploading multiple files
for spec in *.yaml; do
curl ... --data-binary @"$spec"
sleep 10 # Wait 10 seconds between uploads
done
Empty or Invalid Response
Cause: Network issues, incorrect Content-Type, or malformed spec
Solutions:
- Check spec is valid JSON/YAML:
yamllint openapi.yaml - Verify Content-Type header matches file format
- Add
-vflag to curl for debugging:
curl -v -X POST ... --data-binary @openapi.yaml
Managing Tokens
Listing Tokens
View all tokens for a project in the web UI at:
https://restlens.com/projects/[org]/[project]/settings
Revoking Tokens
To revoke a token:
- Go to project settings → API Tokens section
- Find the token to revoke
- Click "Revoke" or "Delete"
- Confirm the action
Note: Revoking a token immediately invalidates it. Any CI/CD pipelines using the token will fail until updated with a new token.
Token Expiration
Expired tokens cannot be used for authentication. To replace an expired token:
- Create a new token
- Update your CI/CD secrets with the new token
- (Optional) Revoke the old token
Security Considerations
- Scope: Each token is scoped to a single project and cannot access other projects
- Revocation: Tokens can be instantly revoked if compromised
- Audit trail: All token usage is logged with timestamps
- No password reset: Tokens cannot be used to change account settings or passwords
- Never share publicly: Don't post tokens in public repositories, forums, or chat