Routeway’s key management endpoints let you create and configure API keys without visiting the dashboard. This is essential for automating key rotation, provisioning keys for new services, and enforcing per-key spending limits.
The full key value is only returned once — when you create it. After that, the key is masked in list and detail responses. Store it securely immediately after creation.
List All Keys
GET /v1/account/keys returns all API keys for your account with masked values.
import os
import requests
headers = { "Authorization" : f "Bearer { os.getenv( 'ROUTEWAY_MANAGEMENT_KEY' ) } " }
response = requests.get( "https://api.routeway.ai/v1/account/keys" , headers = headers)
keys = response.json()[ "data" ]
for key in keys:
print ( f "ID: { key[ 'api_key_id' ] } | Label: { key[ 'label' ] } | Key: { key[ 'key' ] } " )
const response = await fetch ( "https://api.routeway.ai/v1/account/keys" , {
headers: { Authorization: `Bearer ${ process . env . ROUTEWAY_MANAGEMENT_KEY } ` },
});
const { data : keys } = await response . json ();
for ( const key of keys ) {
console . log ( `ID: ${ key . api_key_id } | Label: ${ key . label } | Key: ${ key . key } ` );
}
curl https://api.routeway.ai/v1/account/keys \
-H "Authorization: Bearer $ROUTEWAY_MANAGEMENT_KEY "
Response:
{
"data" : [
{
"api_key_id" : 1 ,
"key" : "rw-abc1234...5678" ,
"label" : "production" ,
"daily_limit" : 1000 ,
"created_at" : "2025-06-01T00:00:00Z"
},
{
"api_key_id" : 2 ,
"key" : "rw-def5678...9012" ,
"label" : "staging" ,
"daily_limit" : 100 ,
"created_at" : "2025-06-10T00:00:00Z"
}
]
}
Create a Key
POST /v1/account/keys creates a new API key with optional configuration.
Parameters
Parameter Type Description labelstring Human-readable name (e.g. "production", "staging") daily_limitinteger Maximum spend or requests per day minute_limitinteger Maximum requests per minute allowed_modelsstring[] Whitelist of model IDs this key can access balancenumber Pre-allocated balance (in dollars) attached to this key use_subs_firstboolean Consume subscription quota before PAYG credit fallback_to_paygboolean Fall back to PAYG when subscription quota is exhausted
import os
import requests
headers = {
"Authorization" : f "Bearer { os.getenv( 'ROUTEWAY_MANAGEMENT_KEY' ) } " ,
"Content-Type" : "application/json"
}
response = requests.post(
"https://api.routeway.ai/v1/account/keys" ,
headers = headers,
json = {
"label" : "backend-service" ,
"daily_limit" : 500 ,
"minute_limit" : 30 ,
"allowed_models" : [ "gpt-4o" , "gpt-4o-mini" , "claude-sonnet-4-20250514" ]
}
)
new_key = response.json()[ "data" ]
print ( f "Key created: { new_key[ 'key' ] } " ) # Save this! Only shown once.
print ( f "ID: { new_key[ 'api_key_id' ] } " )
const response = await fetch ( "https://api.routeway.ai/v1/account/keys" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${ process . env . ROUTEWAY_MANAGEMENT_KEY } ` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({
label: "backend-service" ,
daily_limit: 500 ,
minute_limit: 30 ,
allowed_models: [ "gpt-4o" , "gpt-4o-mini" , "claude-sonnet-4-20250514" ],
}),
});
const { data : newKey } = await response . json ();
console . log ( `Key created: ${ newKey . key } ` ); // Save this! Only shown once.
console . log ( `ID: ${ newKey . api_key_id } ` );
curl https://api.routeway.ai/v1/account/keys \
-H "Authorization: Bearer $ROUTEWAY_MANAGEMENT_KEY " \
-H "Content-Type: application/json" \
-d '{
"label": "backend-service",
"daily_limit": 500,
"minute_limit": 30,
"allowed_models": ["gpt-4o", "gpt-4o-mini", "claude-sonnet-4-20250514"]
}'
The full API key value is only returned in the creation response. Copy and store it in a secrets manager immediately — you cannot retrieve it again.
Get Key Details
GET /v1/account/keys/{key_id} returns detailed information about a specific key, including current usage.
key_id = 1
response = requests.get(
f "https://api.routeway.ai/v1/account/keys/ { key_id } " ,
headers = headers
)
detail = response.json()[ "data" ]
print ( f "Label: { detail[ 'label' ] } " )
print ( f "Usage today: $ { detail[ 'usage_today' ] :.2f} " )
print ( f "Daily limit: { detail[ 'daily_limit' ] } " )
print ( f "Last used: { detail[ 'last_used_at' ] } " )
curl https://api.routeway.ai/v1/account/keys/1 \
-H "Authorization: Bearer $ROUTEWAY_MANAGEMENT_KEY "
Response:
{
"data" : {
"api_key_id" : 1 ,
"key" : "rw-abc1234...5678" ,
"label" : "production" ,
"daily_limit" : 1000 ,
"minute_limit" : 60 ,
"balance" : 10.00 ,
"usage_today" : 3.21 ,
"usage_minute" : 0 ,
"created_at" : "2025-06-01T00:00:00Z" ,
"last_used_at" : "2025-06-15T11:00:00Z" ,
"use_subs_first" : true ,
"fallback_to_payg" : false
}
}
Key Detail Fields
Field Description api_key_idUnique identifier for the key keyMasked key value labelHuman-readable name daily_limitMaximum spend/requests per day minute_limitMaximum requests per minute balancePre-allocated balance on this key usage_todayAmount spent today usage_minuteRequests made in the current minute created_atWhen the key was created last_used_atWhen the key was last used for a request use_subs_firstWhether subscription quota is used before PAYG fallback_to_paygWhether PAYG is used when subscription runs out
Update a Key
PATCH /v1/account/keys/{key_id} updates one or more settings on an existing key. Only include the fields you want to change.
key_id = 1
response = requests.patch(
f "https://api.routeway.ai/v1/account/keys/ { key_id } " ,
headers = headers,
json = {
"label" : "production-v2" ,
"daily_limit" : 2000 ,
"allowed_models" : [ "gpt-4o" , "gpt-4o-mini" ]
}
)
updated = response.json()[ "data" ]
print ( f "Updated key { updated[ 'api_key_id' ] } : { updated[ 'label' ] } " )
curl -X PATCH https://api.routeway.ai/v1/account/keys/1 \
-H "Authorization: Bearer $ROUTEWAY_MANAGEMENT_KEY " \
-H "Content-Type: application/json" \
-d '{
"label": "production-v2",
"daily_limit": 2000
}'
Use updates to adjust limits dynamically — for example, increase a key’s daily_limit during a traffic spike, or tighten allowed_models for a service that should only use cheap models.
Delete a Key
DELETE /v1/account/keys/{key_id} permanently deletes a key. Any requests using this key will immediately start returning 401.
key_id = 2
response = requests.delete(
f "https://api.routeway.ai/v1/account/keys/ { key_id } " ,
headers = headers
)
print (response.json()[ "message" ]) # "API key successfully deleted."
curl -X DELETE https://api.routeway.ai/v1/account/keys/2 \
-H "Authorization: Bearer $ROUTEWAY_MANAGEMENT_KEY "
Response:
{
"message" : "API key successfully deleted."
}
Deletion is permanent and immediate. Any application using this key will lose access instantly. Make sure to rotate keys gracefully — create the new key first, update your services, then delete the old one.
Key Rotation Pattern
A safe key rotation workflow:
import os
import requests
headers = {
"Authorization" : f "Bearer { os.getenv( 'ROUTEWAY_MANAGEMENT_KEY' ) } " ,
"Content-Type" : "application/json"
}
# 1. Create new key with same settings
response = requests.post(
"https://api.routeway.ai/v1/account/keys" ,
headers = headers,
json = { "label" : "production-rotated" , "daily_limit" : 1000 }
)
new_key = response.json()[ "data" ][ "key" ]
print ( f "New key: { new_key } " )
# 2. Deploy new key to your services
# ... update secrets manager, redeploy, etc.
# 3. Verify the new key is working
# ... check activity logs for requests using the new key
# 4. Delete the old key
old_key_id = 1
requests.delete(
f "https://api.routeway.ai/v1/account/keys/ { old_key_id } " ,
headers = headers
)
print ( f "Old key { old_key_id } deleted." )
Best Practices
Use descriptive labels Name keys after the service or environment they belong to (e.g. "prod-backend", "staging-worker"). This makes it easy to audit usage.
Set daily limits Always configure a daily_limit on production keys to prevent runaway costs from bugs or attacks.
Restrict models Use allowed_models to limit expensive models to keys that actually need them. A chatbot key probably doesn’t need access to image generation models.
Rotate regularly Rotate keys periodically (e.g. monthly) and immediately if a key may have been exposed.