POST
/
v2
/
keys.updateKey
Go (SDK)
package main

import(
	"context"
	"os"
	unkey "github.com/unkeyed/sdks/api/go/v2"
	"github.com/unkeyed/sdks/api/go/v2/models/components"
	"log"
)

func main() {
    ctx := context.Background()

    s := unkey.New(
        unkey.WithSecurity(os.Getenv("UNKEY_ROOT_KEY")),
    )

    res, err := s.Keys.UpdateKey(ctx, components.V2KeysUpdateKeyRequestBody{
        KeyID: "key_2cGKbMxRyIzhCxo1Idjz8q",
        Name: unkey.String("Payment Service Production Key"),
        ExternalID: unkey.String("user_912a841d"),
        Meta: map[string]any{
            "plan": "enterprise",
            "limits": map[string]any{
                "storage": "500GB",
                "compute": "1000 minutes/month",
            },
            "features": []any{
                "analytics",
                "exports",
                "webhooks",
            },
            "hasAcceptedTerms": true,
            "billing": map[string]any{
                "cycle": "monthly",
                "next_billing": "2024-01-15",
            },
            "preferences": map[string]any{
                "timezone": "UTC",
                "notifications": true,
            },
            "lastBillingDate": "2023-10-15",
        },
        Expires: unkey.Int64(1704067200000),
        Credits: &components.UpdateKeyCreditsData{
            Remaining: unkey.Int64(1000),
            Refill: &components.UpdateKeyCreditsRefill{
                Interval: components.UpdateKeyCreditsRefillIntervalDaily,
                Amount: 1000,
                RefillDay: unkey.Int64(15),
            },
        },
        Ratelimits: []components.RatelimitRequest{
            components.RatelimitRequest{
                Name: "api",
                Limit: 748124,
                Duration: 784978,
            },
        },
        Enabled: unkey.Bool(true),
        Roles: []string{
            "api_admin",
            "billing_reader",
        },
        Permissions: []string{
            "documents.read",
            "documents.write",
            "settings.view",
        },
    })
    if err != nil {
        log.Fatal(err)
    }
    if res.V2KeysUpdateKeyResponseBody != nil {
        // handle response
    }
}
{
  "data": {},
  "meta": {
    "requestId": "req_01H9TQPP77V5E48E9SH0BG0ZQY"
  }
}

Authorizations

Authorization
string
header
required

Unkey uses API keys (root keys) for authentication. These keys authorize access to management operations in the API. To authenticate, include your root key in the Authorization header of each request:

Authorization: Bearer unkey_123

Root keys have specific permissions attached to them, controlling what operations they can perform. Key permissions follow a hierarchical structure with patterns like resource.resource_id.action (e.g., apis.*.create_key, apis.*.read_api). Security best practices:

  • Keep root keys secure and never expose them in client-side code
  • Use different root keys for different environments
  • Rotate keys periodically, especially after team member departures
  • Create keys with minimal necessary permissions following least privilege principle
  • Monitor key usage with audit logs.

Body

application/json
keyId
string
required

Specifies which key to update using the database identifier returned from createKey. Do not confuse this with the actual API key string that users include in requests.

Required string length: 3 - 255
Example:

"key_2cGKbMxRyIzhCxo1Idjz8q"

name
string | null

Sets a human-readable name for internal organization and identification. Omitting this field leaves the current name unchanged, while setting null removes it entirely. Avoid generic names like "API Key" when managing multiple keys per user or service.

Required string length: 1 - 255
Example:

"Payment Service Production Key"

externalId
string | null

Links this key to a user or entity in your system for ownership tracking during verification. Omitting this field preserves the current association, while setting null disconnects the key from any identity. Essential for user-specific analytics, billing, and key management across multiple users. Supports letters, numbers, underscores, dots, and hyphens for flexible identifier formats.

Required string length: 1 - 255
Example:

"user_912a841d"

meta
object | null

Stores arbitrary JSON metadata returned during key verification. Omitting this field preserves existing metadata, while setting null removes all metadata entirely. Avoid storing sensitive data here as it's returned in verification responses. Large metadata objects increase verification latency and should stay under 10KB total size.

Example:
{
"plan": "enterprise",
"limits": {
"storage": "500GB",
"compute": "1000 minutes/month"
},
"features": ["analytics", "exports", "webhooks"],
"hasAcceptedTerms": true,
"billing": {
"cycle": "monthly",
"next_billing": "2024-01-15"
},
"preferences": { "timezone": "UTC", "notifications": true },
"lastBillingDate": "2023-10-15"
}
expires
integer | null

Sets when this key automatically expires as a Unix timestamp in milliseconds. Verification fails with code=EXPIRED immediately after this time passes. Omitting this field preserves the current expiration, while setting null makes the key permanent.

Avoid setting timestamps in the past as they immediately invalidate the key. Keys expire based on server time, not client time, which prevents timezone-related issues. Active sessions continue until their next verification attempt after expiry.

Required range: 0 <= x <= 4102444800000
Example:

1704067200000

credits
object | null

Controls usage-based limits for this key through credit consumption. Omitting this field preserves current credit settings, while setting null enables unlimited usage. Cannot configure refill settings when credits is null, and refillDay requires monthly interval. Essential for implementing usage-based pricing and subscription quotas.

ratelimits
object[]

Defines time-based rate limits that protect against abuse by controlling request frequency. Omitting this field preserves existing rate limits, while setting null removes all rate limits. Unlike credits which track total usage, rate limits reset automatically after each window expires. Multiple rate limits can control different operation types with separate thresholds and windows.

Maximum length: 50
enabled
boolean

Controls whether the key is currently active for verification requests. When set to false, all verification attempts fail with code=DISABLED regardless of other settings. Omitting this field preserves the current enabled status. Useful for temporarily suspending access during billing issues, security incidents, or maintenance windows without losing key configuration.

Example:

true

roles
string[]
Maximum length: 100

Assigns existing roles to this key for permission management through role-based access control. Roles must already exist in your workspace before assignment. During verification, all permissions from assigned roles are checked against requested permissions. Roles provide a convenient way to group permissions and apply consistent access patterns across multiple keys.

Example:
["api_admin", "billing_reader"]
permissions
string[]
Maximum length: 1000

Grants specific permissions directly to this key without requiring role membership. Wildcard permissions like documents.* grant access to all sub-permissions including documents.read and documents.write. Direct permissions supplement any permissions inherited from assigned roles.

Example:
[
"documents.read",
"documents.write",
"settings.view"
]

Response

Key updated successfully. Changes take effect immediately with up to 30-second edge propagation.

meta
object
required

Metadata object included in every API response. This provides context about the request and is essential for debugging, audit trails, and support inquiries. The requestId is particularly important when troubleshooting issues with the Unkey support team.

data
object
required

Empty response object by design. A successful response indicates this operation was successfully executed.