Skip to main content
Temporary keys automatically become invalid after a specified time. No cleanup required — Unkey handles expiration and deletion for you.

When to use this

Trial access

Give new users a 7-day trial key. It stops working automatically.

Time-limited integrations

Partner needs API access for a project? Key expires when the project ends.

Session-based access

Generate a key that lasts for a user’s session (e.g., 24 hours).

Security rotations

Force key rotation by having keys expire periodically.

How it works

  1. Create a key with an expires timestamp (Unix milliseconds)
  2. Key works normally until the expiration time
  3. After expiration, verification returns code: EXPIRED
  4. Unkey automatically cleans up expired keys

Create a temporary key

Set expires to a Unix timestamp in milliseconds:
# Key expires in 24 hours
EXPIRES=$(($(date +%s) * 1000 + 86400000))

curl -X POST https://api.unkey.com/v2/keys.createKey \
  -H "Authorization: Bearer $UNKEY_ROOT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "apiId": "api_...",
    "expires": '$EXPIRES'
  }'

Common expiration times

DurationCalculation
1 hourDate.now() + 60 * 60 * 1000
24 hoursDate.now() + 24 * 60 * 60 * 1000
7 daysDate.now() + 7 * 24 * 60 * 60 * 1000
30 daysDate.now() + 30 * 24 * 60 * 60 * 1000
Specific datenew Date("2024-12-31").getTime()

Verification response

When verifying an expired key:
{
  "meta": { "requestId": "req_..." },
  "data": {
    "valid": false,
    "code": "EXPIRED",
    "keyId": "key_..."
  }
}

Extend or change expiration

Update the expiration time on an existing key:
# Extend by 7 more days from now
EXPIRES=$(($(date +%s) * 1000 + 604800000))

curl -X POST https://api.unkey.com/v2/keys.updateKey \
  -H "Authorization: Bearer $UNKEY_ROOT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "keyId": "key_...",
    "expires": '$EXPIRES'
  }'

Remove expiration

Make a temporary key permanent by setting expires to null:
curl -X POST https://api.unkey.com/v2/keys.updateKey \
  -H "Authorization: Bearer $UNKEY_ROOT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "keyId": "key_...",
    "expires": null
  }'

Combining with other features

Temporary keys work with all other key features:
// 7-day trial with 1000 requests and rate limiting
try {
  const { meta, data } = await unkey.keys.create({
    apiId: "api_...",
    expires: Date.now() + 7 * 24 * 60 * 60 * 1000,
    credits: {
      remaining: 1000,
    },
    ratelimits: [{
      name: "requests",
      limit: 100,
      duration: 60000,  // 100 per minute
    }],
  });
} catch (err) {
  console.error(err);
  return Response.json({ error: "Internal error" }, { status: 500 });
}

Temporary vs usage-limited keys

FeatureTemporary KeysUsage-Limited Keys
Controlled byTimeRequest count
Expires whenClock hits timestampCredits reach 0
Good forTime-bound accessPay-per-use, quotas
Example”Access for 7 days""1000 requests total”
Use both together for trial limits: “7 days OR 1000 requests, whichever comes first.”

Next steps

Last modified on February 16, 2026