.claude/skills/terra-auth/SKILL.md
Terra API authentication, credentials management, and environment configuration. Use when setting up Terra integration, managing API keys, generating widget sessions, or configuring testing/staging/production environments.
npx skillsauth add adaptationio/skrillz terra-authInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Manage Terra API authentication across testing, staging, and production environments.
Credentials are stored in environment-specific .env files:
| Environment | File |
|-------------|------|
| Testing | .env.terra.testing |
| Staging | .env.terra.staging |
| Production | .env.terra.production |
Load credentials:
from dotenv import load_dotenv
import os
# Load specific environment
load_dotenv(".env.terra.testing")
dev_id = os.getenv("TERRA_DEV_ID")
api_key = os.getenv("TERRA_API_KEY")
Or use the helper:
from scripts.terra_client import get_terra_client
client = get_terra_client("testing") # or "staging", "production"
from terra import Terra
# Testing environment - load from .env.terra.testing
client = Terra(
dev_id=os.environ["TERRA_DEV_ID"],
api_key=os.environ["TERRA_API_KEY"]
)
# Verify connection
integrations = client.integrations.fetch()
print(f"Connected! {len(integrations.integrations)} providers available")
# .env.testing
TERRA_DEV_ID=your-dev-id-here
TERRA_API_KEY=your-api-key-here
# .env.staging
TERRA_DEV_ID=your-staging-dev-id
TERRA_API_KEY=your-staging-api-key
# .env.production
TERRA_DEV_ID=your-production-dev-id
TERRA_API_KEY=your-production-api-key
setup-environmentConfigure Terra credentials for specific environment.
Python:
import os
from terra import Terra
def get_terra_client(env: str = "testing") -> Terra:
"""Get Terra client for specified environment."""
configs = {
"testing": {
"dev_id": os.environ.get("TERRA_DEV_ID_TESTING"),
"api_key": os.environ.get("TERRA_API_KEY_TESTING")
},
"staging": {
"dev_id": os.environ.get("TERRA_DEV_ID_STAGING"),
"api_key": os.environ.get("TERRA_API_KEY_STAGING")
},
"production": {
"dev_id": os.environ.get("TERRA_DEV_ID_PRODUCTION"),
"api_key": os.environ.get("TERRA_API_KEY_PRODUCTION")
}
}
config = configs.get(env)
if not config:
raise ValueError(f"Unknown environment: {env}")
return Terra(dev_id=config["dev_id"], api_key=config["api_key"])
# Usage
client = get_terra_client("testing")
generate-widget-sessionCreate authentication widget URL for end users.
Python:
def generate_widget_session(
client: Terra,
reference_id: str,
success_url: str,
failure_url: str,
providers: list[str] = None
) -> str:
"""Generate widget session URL for user authentication."""
response = client.authentication.generatewidgetsession(
reference_id=reference_id,
auth_success_redirect_url=success_url,
auth_failure_redirect_url=failure_url,
providers=providers # Optional: filter providers ["FITBIT", "GARMIN"]
)
return response.url
# Usage
widget_url = generate_widget_session(
client=client,
reference_id="user_12345", # Your internal user ID
success_url="https://app.botaniqal.com/terra/success",
failure_url="https://app.botaniqal.com/terra/failure"
)
print(f"Redirect user to: {widget_url}")
Response:
{
"url": "https://widget.tryterra.co/session/abc123...",
"session_id": "abc123...",
"expires_at": "2025-12-05T12:15:00Z"
}
generate-mobile-tokenGenerate authentication token for mobile SDK.
Python:
def generate_mobile_token(client: Terra) -> str:
"""Generate token for mobile SDK initialization.
Note: Token is generated for the account, not per-user.
Use reference_id in the mobile SDK init to identify users.
"""
response = client.authentication.generateauthtoken()
return response.token
# Usage (backend endpoint)
@app.route("/api/terra/mobile-token", methods=["POST"])
@login_required
def get_mobile_token():
token = generate_mobile_token(client=terra_client)
# Pass reference_id to mobile SDK, not to token generation
return jsonify({
"token": token,
"reference_id": str(current_user.id) # For SDK init
})
Token Expiration: 180 seconds (3 minutes), one-time use.
deauthenticate-userRemove user and revoke data access.
Python:
def deauthenticate_user(client: Terra, user_id: str) -> bool:
"""Deauthenticate user and remove their data."""
response = client.authentication.deauthenticateuser(user_id=user_id)
return response.success
# Usage
success = deauthenticate_user(client, "terra_user_abc123")
if success:
print("User deauthenticated successfully")
list-integrationsGet all available provider integrations.
Python:
def list_integrations(client: Terra) -> list:
"""List all available Terra integrations."""
response = client.integrations.fetch()
integrations = []
for integration in response.integrations:
integrations.append({
"name": integration.name,
"resource": integration.resource,
"logo_url": integration.logo_url
})
return integrations
# Usage
providers = list_integrations(client)
for p in providers:
print(f"{p['name']}: {p['resource']}")
All REST API calls require these headers:
dev-id: <YOUR_DEV_ID>
x-api-key: <YOUR_API_KEY>
Content-Type: application/json
cURL Example:
curl -X GET "https://api.tryterra.co/v2/integrations" \
-H "dev-id: $TERRA_DEV_ID" \
-H "x-api-key: $TERRA_API_KEY"
Each environment has a unique signing secret for webhook verification:
terra-webhooks skill for implementation| Token Type | Expiration | Notes | |------------|------------|-------| | Widget Session | 15 minutes | URL valid until used or expired | | Mobile SDK Token | 3 minutes | One-time use, generate per connection | | OAuth Tokens | Auto-refresh | Terra manages automatically | | API Keys | Never | Rotate manually if needed |
| Environment | Base URL |
|-------------|----------|
| Production API | https://api.tryterra.co |
| Widget | https://widget.tryterra.co |
| Streaming | wss://streaming.tryterra.co |
development
Setup secure web-based terminal access to WSL2 from mobile/tablet via ttyd + ngrok/Cloudflare/Tailscale. One-command install, start, stop, status. Use when you need remote terminal access, web terminal, browser-based shell, or mobile access to WSL2 environment.
development
Complete development workflows where Claude writes the code while Gemini and Codex provide research, planning, reviews, and different perspectives. Claude remains the main developer. Use for complex projects requiring expert planning and multi-perspective reviews.
development
Systematic progress tracking for skill development. Manages task states (pending/in_progress/completed), updates in real-time, reports progress, identifies blockers, and maintains momentum. Use when tracking skill development, coordinating work, or reporting progress.
testing
Comprehensive testing workflow orchestrating functional testing, example validation, integration testing, and usability assessment. Sequential workflow for complete skill testing from examples through scenarios to integration validation. Use when conducting thorough testing, pre-deployment validation, ensuring skill functionality, or comprehensive quality checks.