API Management
Programmatically manage your API tokens and OAuth apps using the API Management endpoints. This guide shows you how to create, update, rotate and delete credentials via API—perfect for automation and DevOps workflows.
Overview
The API Management endpoints allow you to manage your authentication credentials programmatically. This is useful for:
- Automated credential rotation - Schedule regular token updates for security compliance
- Multi-environment setup - Programmatically provision credentials across dev, staging and production
- CI/CD integration - Create temporary tokens for build pipelines
- Infrastructure as Code - Manage credentials alongside your infrastructure definitions
- Self-service platforms - Allow your users to manage their own API credentials
All API Management endpoints require authentication with the credentials.manage scope. You must use existing valid credentials (API token or OAuth access token) with this scope to manage your credentials.
Base URL
https://manage.youriguide.com/api/v1
Authentication
All API Management endpoints require authentication using the standard headers:
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN"
Available scopes
Before creating credentials, you should understand the available scopes. Each scope grants specific permissions:
Get available scopes
Retrieve the list of all available OAuth and API token scopes. This is a public endpoint that doesn't require authentication.
Endpoint: GET /scopes
Example:
curl https://manage.youriguide.com/api/v1/scopes
Response:
[
"iguide.list",
"iguide.ro",
"iguide.rw",
"iguide.tasks",
"iguide.billing",
"iguide.gallery",
"iguide.events",
"iguide.draft.ro",
"viewer.data",
"banner.list",
"credentials.manage"
]
Scope descriptions
| Scope | Description | Use Cases |
|---|---|---|
iguide.list | List user's iGUIDEs and access metadata (read-only) | Dashboard displays, search functionality |
iguide.ro | Read iGUIDE metadata (excludes billing) | Public integrations, viewer apps |
iguide.rw | Read and write iGUIDE data (includes iguide.ro, excludes billing/tasks) | Data synchronization, gallery management |
iguide.tasks | Create and manage iGUIDE tasks and work orders | Order management systems, scheduling tools |
iguide.billing | Access billing information | Accounting integrations, invoicing systems |
iguide.gallery | Upload and remove gallery images | Photo management tools |
iguide.events | Receive and access iGUIDE events, dispatch webhooks | Real-time integrations, notification systems |
iguide.draft.ro | Download iGUIDE draft data | Data processing pipelines |
viewer.data | Access Viewer API data endpoints (includes RESO) | MLS integrations, property data syndication |
banner.list | Access public banners | Contact information displays |
credentials.manage | Manage API tokens and OAuth applications | Automated credential rotation, DevOps workflows |
The iguide.rw scope automatically includes all permissions from iguide.ro. Choose the most specific scope that matches your needs.
Managing API tokens
API tokens are JWT-based credentials perfect for server-to-server integrations. Each user can have up to 10 active tokens.
List API tokens
Retrieve all API tokens for the authenticated user.
Endpoint: GET /tokens
Example:
curl https://manage.youriguide.com/api/v1/tokens \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN"
Response:
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Production API Token",
"description": "Token for production environment",
"scopes": ["iguide.list", "iguide.ro", "iguide.tasks"],
"tokenHint": "...abc123",
"expiresAt": "2028-02-21T12:00:00Z",
"createdAt": "2026-02-21T12:00:00Z",
"lastUsedAt": "2026-02-23T10:30:00Z"
}
]
Response fields:
| Field | Type | Description |
|---|---|---|
id | string | Token identifier (UUID) - use this as X-Plntr-App-Id |
name | string | Display name for the token |
description | string | Optional description |
scopes | array | Granted permission scopes |
tokenHint | string | Last 4 characters of the token (for identification) |
expiresAt | string | ISO 8601 expiration timestamp (null if no expiration) |
createdAt | string | ISO 8601 creation timestamp |
lastUsedAt | string | ISO 8601 last usage timestamp (null if never used) |
Full token values are never returned in list operations. They're only shown once during creation or rotation.
Create API token
Create a new API token with specified scopes and optional expiration.
Endpoint: POST /tokens
Request body:
{
"name": "Production API Token",
"description": "Token for production environment",
"scopes": ["iguide.list", "iguide.ro", "iguide.tasks"],
"expiresAt": "2028-02-21T12:00:00Z"
}
Request fields:
| Field | Required | Type | Description |
|---|---|---|---|
name | Yes | string | Display name for the token |
description | No | string | Optional description |
scopes | Yes | array | List of requested scopes (must be valid scope strings) |
expiresAt | No | string | ISO 8601 expiration date (defaults to 2 years if omitted) |
Example:
curl -X POST https://manage.youriguide.com/api/v1/tokens \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Production API Token",
"description": "Token for production environment",
"scopes": ["iguide.list", "iguide.ro", "iguide.tasks"],
"expiresAt": "2028-02-21T12:00:00Z"
}'
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Production API Token",
"description": "Token for production environment",
"scopes": ["iguide.list", "iguide.ro", "iguide.tasks"],
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
"tokenHint": "...ssw5c",
"expiresAt": "2028-02-21T12:00:00Z",
"createdAt": "2026-02-21T12:00:00Z"
}
The full token value is only returned once when you create the token. Store it securely—you won't be able to retrieve it again. If you lose it, you'll need to rotate the token to get a new value.
Usage:
Use the returned values in API requests:
id→X-Plntr-App-Idheadertoken→X-Plntr-App-Tokenheader
When using app-based authentication, you can only assign scopes that your requesting app already has. This prevents privilege escalation. Session-based authentication bypasses this validation.
Rotate API token
Generate a new token value while keeping the same token ID. The old token remains valid during a configurable grace period (default: 7 days), enabling zero-downtime credential updates.
Endpoint: POST /tokens/{tokenId}/rotate
Path parameters:
| Parameter | Type | Description |
|---|---|---|
tokenId | string | Token ID (UUID) |
Example:
curl -X POST https://manage.youriguide.com/api/v1/tokens/550e8400-e29b-41d4-a716-446655440000/rotate \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN"
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Production API Token",
"description": "Token for production environment",
"scopes": ["iguide.list", "iguide.ro", "iguide.tasks"],
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.NEW_TOKEN_VALUE.xyz789",
"tokenHint": "...xyz789",
"expiresAt": "2028-02-21T12:00:00Z",
"createdAt": "2026-02-21T12:00:00Z",
"previousToken": {
"hint": "...ssw5c",
"status": "active",
"expiresAt": "2026-02-28T12:00:00Z"
}
}
Previous token info:
| Field | Type | Description |
|---|---|---|
hint | string | Last 4 characters of the previous token |
status | string | Token status: active, expired, or revoked |
expiresAt | string | When the previous token will expire (ISO 8601) |
Rotation workflow:
- Rotate the token - Call the rotate endpoint to get a new token value
- Grace period begins - Both old and new tokens are valid
- Update your systems - Deploy the new token to your applications
- Verify functionality - Test that your applications work with the new token
- Optional: Revoke previous - Manually end the grace period early (see below)
- Grace period ends - Old token automatically expires after 7 days
Token rotation enables you to update credentials without any service interruption. Deploy the new token to all systems during the grace period, then optionally revoke the old token once you've verified everything works.
Revoke previous token
Manually revoke the previous token after rotation, ending the grace period early. Use this after confirming all systems have been updated to use the new token.
Endpoint: POST /tokens/{tokenId}/revokePrevious
Path parameters:
| Parameter | Type | Description |
|---|---|---|
tokenId | string | Token ID (UUID) - the current active token, not the previous one |
Example:
curl -X POST https://manage.youriguide.com/api/v1/tokens/550e8400-e29b-41d4-a716-446655440000/revokePrevious \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN"
Response:
{
"ok": true
}
Revoking the previous token immediately invalidates it. Any systems still using the old token will start receiving 401 Unauthorized errors. Only revoke after verifying all systems are using the new token.
Delete API token
Permanently delete an API token and immediately invalidate it.
Endpoint: DELETE /tokens/{tokenId}
Path parameters:
| Parameter | Type | Description |
|---|---|---|
tokenId | string | Token ID (UUID) |
Example:
curl -X DELETE https://manage.youriguide.com/api/v1/tokens/550e8400-e29b-41d4-a716-446655440000 \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN"
Response:
{
"ok": true
}
Tokens are soft-deleted for audit trail purposes. The token is immediately invalidated but not physically removed from the database.
Managing OAuth apps
OAuth apps enable standard OAuth 2.0 authorization flows for user-facing applications. Each user can have up to 10 active OAuth apps.
List OAuth apps
Retrieve all OAuth applications for the authenticated user.
Endpoint: GET /apps
Example:
curl https://manage.youriguide.com/api/v1/apps \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN"
Response:
[
{
"clientId": "660e8400-e29b-41d4-a716-446655440001",
"clientName": "My Web Application",
"description": "OAuth app for web application",
"redirectUris": ["https://myapp.com/oauth/callback"],
"logoUri": "https://myapp.com/logo.png",
"scope": ["iguide.list", "iguide.ro"],
"clientSecretHint": "...def456",
"clientIdIssuedAt": "2026-02-21T12:00:00Z",
"updatedAt": "2026-02-21T12:00:00Z"
}
]
Response fields:
| Field | Type | Description |
|---|---|---|
clientId | string | Client identifier (UUID) - use as X-Plntr-App-Id |
clientName | string | Application name (shown to users during authorization) |
description | string | Application description |
redirectUris | array | Registered OAuth callback URLs |
logoUri | string | Application logo URL |
scope | array | Granted permission scopes |
clientSecretHint | string | Last 4 characters of client secret |
clientIdIssuedAt | string | ISO 8601 timestamp when client ID was issued |
updatedAt | string | ISO 8601 last update timestamp |
Client secrets are never returned in list or get operations. They're only shown once during creation or rotation.
Get OAuth app
Retrieve a specific OAuth application by ID.
Endpoint: GET /apps/{appId}
Path parameters:
| Parameter | Type | Description |
|---|---|---|
appId | string | OAuth app ID (UUID) |
Example:
curl https://manage.youriguide.com/api/v1/apps/660e8400-e29b-41d4-a716-446655440001 \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN"
Response:
{
"clientId": "660e8400-e29b-41d4-a716-446655440001",
"clientName": "My Web Application",
"description": "OAuth app for web application",
"redirectUris": ["https://myapp.com/oauth/callback"],
"logoUri": "https://myapp.com/logo.png",
"scope": ["iguide.list", "iguide.ro"],
"clientSecretHint": "...def456",
"clientIdIssuedAt": "2026-02-21T12:00:00Z",
"updatedAt": "2026-02-21T12:00:00Z"
}
Create OAuth app
Create a new OAuth application with an auto-generated client secret.
Endpoint: POST /apps
Request body:
{
"clientName": "My Web Application",
"description": "OAuth app for web application",
"redirectUris": [
"https://myapp.com/oauth/callback",
"https://myapp.com/oauth/callback2"
],
"logoUri": "https://myapp.com/logo.png",
"scope": ["iguide.list", "iguide.ro"]
}
Request fields:
| Field | Required | Type | Description |
|---|---|---|---|
clientName | Yes | string | Application name (shown to users during authorization) |
description | No | string | Application description |
redirectUris | Yes | array | One or more OAuth callback URLs (must be valid URIs) |
logoUri | No | string | Application logo URL (must be valid URI) |
scope | Yes | array | List of requested scopes (must be valid scope strings) |
Example:
curl -X POST https://manage.youriguide.com/api/v1/apps \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"clientName": "My Web Application",
"description": "OAuth app for web application",
"redirectUris": ["https://myapp.com/oauth/callback"],
"logoUri": "https://myapp.com/logo.png",
"scope": ["iguide.list", "iguide.ro"]
}'
Response:
{
"clientId": "660e8400-e29b-41d4-a716-446655440001",
"clientName": "My Web Application",
"description": "OAuth app for web application",
"redirectUris": ["https://myapp.com/oauth/callback"],
"logoUri": "https://myapp.com/logo.png",
"scope": ["iguide.list", "iguide.ro"],
"clientSecret": "sk_live_51H8F2KLbZqZ1X2Y3Z4W5V6U7T8S9R0Q1P2O3N4M5L6K7J8I9H0G1F2E3D4C5B6A",
"clientSecretHint": "...5B6A",
"clientIdIssuedAt": "2026-02-21T12:00:00Z",
"updatedAt": "2026-02-21T12:00:00Z"
}
The clientSecret is only returned once when you create the app. Store it securely—treat it like a password. If you lose it, you'll need to rotate the secret to get a new value.
Security features:
- XSS prevention - All text fields are sanitized
- SSRF protection - All URLs are validated for security
- SHA-256 hashing - Client secrets are securely hashed before storage
When using app-based authentication, you can only assign scopes that your requesting app already has. This prevents privilege escalation. Session-based authentication bypasses this validation.
Update OAuth app
Update an existing OAuth application. Supports partial updates—only provide the fields you want to change.
Endpoint: PATCH /apps/{appId}
Path parameters:
| Parameter | Type | Description |
|---|---|---|
appId | string | OAuth app ID (UUID) |
Request body (all fields optional):
{
"clientName": "My Updated Application",
"description": "Updated description",
"redirectUris": ["https://myapp.com/new-callback"],
"logoUri": "https://myapp.com/new-logo.png",
"scope": ["iguide.list", "iguide.ro", "iguide.rw"]
}
Example:
curl -X PATCH https://manage.youriguide.com/api/v1/apps/660e8400-e29b-41d4-a716-446655440001 \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"clientName": "My Updated Application",
"scope": ["iguide.list", "iguide.ro", "iguide.rw"]
}'
Response:
{
"clientId": "660e8400-e29b-41d4-a716-446655440001",
"clientName": "My Updated Application",
"description": "OAuth app for web application",
"redirectUris": ["https://myapp.com/oauth/callback"],
"logoUri": "https://myapp.com/logo.png",
"scope": ["iguide.list", "iguide.ro", "iguide.rw"],
"clientSecretHint": "...def456",
"clientIdIssuedAt": "2026-02-21T12:00:00Z",
"updatedAt": "2026-02-23T10:30:00Z"
}
You cannot update the client secret via this endpoint. Use the rotate endpoint instead.
When updating scopes via app-based authentication, you can only assign scopes that your requesting app already has. This prevents privilege escalation. Session-based authentication bypasses this validation.
Rotate OAuth app secret
Generate a new client secret for an OAuth application, immediately invalidating the old secret. Use this when a secret has been compromised or as part of regular security rotation.
Endpoint: POST /apps/{appId}/rotate
Path parameters:
| Parameter | Type | Description |
|---|---|---|
appId | string | OAuth app ID (UUID) |
Example:
curl -X POST https://manage.youriguide.com/api/v1/apps/660e8400-e29b-41d4-a716-446655440001/rotate \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN"
Response:
{
"clientId": "660e8400-e29b-41d4-a716-446655440001",
"clientName": "My Web Application",
"description": "OAuth app for web application",
"redirectUris": ["https://myapp.com/oauth/callback"],
"logoUri": "https://myapp.com/logo.png",
"scope": ["iguide.list", "iguide.ro"],
"clientSecret": "sk_live_NEW_SECRET_VALUE_HERE",
"clientSecretHint": "...HERE",
"clientIdIssuedAt": "2026-02-21T12:00:00Z",
"updatedAt": "2026-02-23T10:30:00Z"
}
Unlike API token rotation, OAuth secret rotation immediately invalidates the old secret. There is no grace period. Update your application with the new secret before rotating to avoid downtime.
Delete OAuth app
Permanently delete an OAuth application, immediately invalidating it and revoking all associated tokens.
Endpoint: DELETE /apps/{appId}
Path parameters:
| Parameter | Type | Description |
|---|---|---|
appId | string | OAuth app ID (UUID) |
Example:
curl -X DELETE https://manage.youriguide.com/api/v1/apps/660e8400-e29b-41d4-a716-446655440001 \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN"
Response:
{
"ok": true
}
Deleting an OAuth app immediately revokes all access tokens and refresh tokens issued by that app. Users will need to re-authorize if you recreate the app.
Error handling
All API Management endpoints return standard error responses:
400 Bad Request
Invalid request data or validation errors:
{
"code": "invalid_argument",
"message": "Invalid request body"
}
Common causes:
- Invalid JSON format
- Missing required fields
- Invalid UUID format
- Invalid scope names
- Invalid URL formats
401 Unauthorized
Authentication failed:
{
"code": "unauthenticated",
"message": "Unauthorized request"
}
Common causes:
- Missing authentication headers
- Invalid or expired credentials
404 Not Found
Resource doesn't exist or access denied:
{
"code": "not_found",
"message": "App not found"
}
Common causes:
- Invalid token ID or app ID
- Attempting to access another user's credentials
- Resource already deleted
409 Conflict
User has reached resource limit:
{
"code": "resource_exhausted",
"message": "Maximum number of API tokens reached"
}
Limits:
- Maximum 10 API tokens per user
- Maximum 10 OAuth apps per user
500 Internal Server Error
Server-side error:
{
"code": "internal",
"message": "Internal server error"
}
If errors persist, please contact support.
Automation examples
Automated token rotation script
Rotate API tokens on a schedule for security compliance:
#!/bin/bash
set -e
# Configuration
TOKEN_ID="550e8400-e29b-41d4-a716-446655440000"
CURRENT_APP_ID="$TOKEN_ID"
CURRENT_APP_TOKEN="your-current-token"
echo "Rotating token $TOKEN_ID..."
# Rotate the token
RESPONSE=$(curl -s -X POST \
"https://manage.youriguide.com/api/v1/tokens/$TOKEN_ID/rotate" \
-H "X-Plntr-App-Id: $CURRENT_APP_ID" \
-H "X-Plntr-App-Token: $CURRENT_APP_TOKEN")
# Extract new token
NEW_TOKEN=$(echo $RESPONSE | jq -r '.token')
GRACE_PERIOD_END=$(echo $RESPONSE | jq -r '.previousToken.expiresAt')
echo "✓ Token rotated successfully"
echo "New token: $NEW_TOKEN"
echo "Grace period ends: $GRACE_PERIOD_END"
echo ""
echo "Update your applications with the new token before: $GRACE_PERIOD_END"
Provision credentials for new environment
Automatically create credentials for a new deployment environment:
#!/bin/bash
set -e
ENVIRONMENT=${1:-staging}
APP_ID="your-app-id"
APP_TOKEN="your-token"
echo "Creating credentials for $ENVIRONMENT environment..."
# Create API token
RESPONSE=$(curl -s -X POST \
"https://manage.youriguide.com/api/v1/tokens" \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"name\": \"$ENVIRONMENT API Token\",
\"description\": \"Auto-provisioned token for $ENVIRONMENT\",
\"scopes\": [\"iguide.list\", \"iguide.ro\", \"iguide.tasks\"],
\"expiresAt\": \"$(date -u -d '+2 years' +%Y-%m-%dT%H:%M:%SZ)\"
}")
TOKEN_ID=$(echo $RESPONSE | jq -r '.id')
TOKEN_VALUE=$(echo $RESPONSE | jq -r '.token')
echo "✓ Credentials created for $ENVIRONMENT"
echo ""
echo "Add these to your $ENVIRONMENT environment:"
echo "APP_ID=$TOKEN_ID"
echo "APP_TOKEN=$TOKEN_VALUE"
Audit credential usage
List all credentials and their usage:
#!/bin/bash
APP_ID="your-app-id"
APP_TOKEN="your-token"
echo "=== API Tokens ==="
curl -s "https://manage.youriguide.com/api/v1/tokens" \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN" \
| jq -r '.[] | "\(.name): last used \(.lastUsedAt // "never")"'
echo ""
echo "=== OAuth Apps ==="
curl -s "https://manage.youriguide.com/api/v1/apps" \
-H "X-Plntr-App-Id: $APP_ID" \
-H "X-Plntr-App-Token: $APP_TOKEN" \
| jq -r '.[] | "\(.clientName): created \(.clientIdIssuedAt)"'
Best practices
Security
- Protect your credentials - API Management endpoints require authentication. Protect these credentials carefully
- Rotate regularly - Implement automated rotation schedules for production tokens
- Use minimum scopes - Create credentials with only the scopes they need
- Audit regularly - Review and remove unused credentials
- Monitor usage - Track credential usage via the
lastUsedAtfield
Automation
- Idempotent operations - Make your scripts handle cases where credentials already exist
- Error handling - Always check for 409 Conflict errors when creating credentials
- Store securely - Use secure secret management (HashiCorp Vault, AWS Secrets Manager, etc.)
- Version control - Never commit credentials to version control
- Environment separation - Use different credentials for dev, staging and production
Token rotation
- Schedule rotations - Rotate tokens quarterly or when security events occur
- Use grace period - Take advantage of the 7-day grace period for zero-downtime updates
- Test first - Rotate and test in staging before production
- Monitor expiration - Track
previousToken.expiresAtto ensure timely updates - Revoke promptly - Use
revokePreviousonce all systems are updated
Limits and constraints
| Resource | Limit | Notes |
|---|---|---|
| API tokens per user | 10 | Both active and rotated (during grace period) count toward limit |
| OAuth apps per user | 10 | Soft-deleted apps don't count toward limit |
| Token grace period | 7 days | Configurable, default is 7 days |
| Default token expiration | 2 years | Can be customized per token |
| Client secret length | 64 characters | Auto-generated, SHA-256 hashed |
| API token length | Variable (JWT) | Signed JWT containing claims |
Next steps
- Learn about Authentication to understand how to use the credentials you create
- Explore Rate Limiting to understand API usage limits
- Follow the Your First iGUIDE tutorial
- Check the API Reference for complete endpoint documentation
Related resources
- Authentication Guide - How to use API tokens and OAuth apps
- Security Best Practices - Secure credential management
- OAuth 2.0 Flow - Implementing OAuth authorization
- Rate Limiting - API usage limits and quotas