### Clone Unkey Repository and Install Dependencies (Bash) Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/quickstart.mdx This snippet clones the Unkey repository, navigates into the directory, and installs all necessary dependencies using 'make install'. It sets up the Go workspace and installs web dependencies. ```bash git clone https://github.com/unkeyed/unkey cd unkey make install ``` -------------------------------- ### Initialize Bun Project and Install SDK Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/quickstart/apis/bun.mdx This snippet covers the initial setup for a Bun project. It includes commands to create a new directory, initialize a Bun project, and install the necessary Unkey SDK package. These steps are fundamental for starting the development process. ```bash mkdir unkey-bun && cd unkey-bun bun init -y bun add @unkey/api ``` -------------------------------- ### Go Quickstart: Basic and Advanced HTTP Server Setup Source: https://github.com/unkeyed/unkey/blob/main/pkg/zen/README.md This Go code demonstrates how to set up a minimalist HTTP server using the Zen framework. It includes examples of a simple 'Hello, world!' route, a POST endpoint with request body parsing and validation, and middleware integration for logging, error handling, and observability. It utilizes Go's standard library for networking and context management. ```go package main import ( "context" "log" "log/slog" "net" "net/http" "github.com/unkeyed/unkey/pkg/zen" "github.com/unkeyed/unkey/pkg/logger" "github.com/unkeyed/unkey/pkg/zen/validation" "github.com/unkeyed/unkey/pkg/fault" ) // Request struct for our create user endpoint type CreateUserRequest struct { Name string `json:"name"` Email string `json:"email"` Password string `json:"password"` } // Response for successful user creation type CreateUserResponse struct { ID string `json:"id"` Name string `json:"name"` Email string `json:"email"` } func main() { // Create a new server server, err := zen.New(zen.Config{ NodeID: "quickstart-server", }) if err != nil { log.Fatalf("failed to create server: %v", err) } // Initialize OpenAPI validator // see the validation package how we pass in the openapi spec validator, err := validation.New() if err != nil { log.Fatalf("failed to create validator: %v", err) } // Simple hello world route helloRoute := zen.NewRoute("GET", "/hello", func(ctx context.Context, s *zen.Session) error { return s.JSON(http.StatusOK, map[string]string{ "message": "Hello, world!", }) }) // POST endpoint with request validation and error handling createUserRoute := zen.NewRoute("POST", "/users", func(ctx context.Context, s *zen.Session) error { // Parse request body var req CreateUserRequest req, err := zen.BindBody[CreateUserRequest](s) if err != nil { return err } // Additional validation logic if len(req.Password) < 8 { return fault.New("password too short", fault.WithTag(fault.BAD_REQUEST), fault.WithDesc( "password must be at least 8 characters", // Internal description "Password must be at least 8 characters long" // User-facing message ), ) } // Process the request (in a real app, you'd save to database etc.) userID := "user_pretendthisisrandom" // Return response return s.JSON(http.StatusCreated, CreateUserResponse{ ID: userID, Name: req.Name, Email: req.Email, }) }) // Register routes with middleware server.RegisterRoute( []zen.Middleware{ zen.WithLogging(), zen.WithErrorHandling(), }, helloRoute, ) server.RegisterRoute( []zen.Middleware{ zen.WithObservability(), zen.WithLogging(), zen.WithErrorHandling(), zen.WithValidation(validator), }, createUserRoute, ) // Start the server logger.Info("starting server", "address", ":8080", ) // Create a listener listener, err := net.Listen("tcp", ":8080") if err != nil { log.Fatalf("failed to create listener: %v", err) } err = server.Serve(context.Background(), listener) if err != nil { logger.Error("server error", slog.String("error", err.Error())) } } ``` -------------------------------- ### Start Local Dashboard Development (Bash) Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/quickstart.mdx This command initiates the local development environment for the Unkey dashboard. It starts required backend services using Docker Compose, creates necessary .env files, and launches the dashboard development server. ```bash make local-dashboard ``` -------------------------------- ### Basic Rate Limiter Usage Example in Go Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/documentation.mdx Demonstrates the typical setup and usage of the rate limiter, including configuration, initialization, and making an Allow call. It highlights error handling and successful request logging. This example is suitable for showcasing non-trivial usage patterns. ```go // Example_basicUsage demonstrates typical rate limiter setup and usage. func Example_basicUsage() { cfg := Config{ Window: time.Minute, Limit: 1000, ClusterNodes: []string{"localhost:8080"}, } limiter, err := New(cfg) if err != nil { log.Fatal(err) } defer limiter.Close() allowed, err := limiter.Allow(context.Background(), "user:alice", 5) if err != nil { log.Printf("System error: %v", err) return } if !allowed { log.Println("Rate limit exceeded") return } log.Println("Request allowed") // Output: Request allowed } ``` -------------------------------- ### Configure Depot Environment Variables (Bash) Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/quickstart.mdx This snippet copies an example Depot environment file and renames it for use. It's a required step for the current backend development setup, and users need to edit the file with their Depot credentials. ```bash cp ./dev/.env.depot.example ./dev/.env.depot # Edit ./dev/.env.depot with your Depot credentials ``` -------------------------------- ### Start Minikube Tunnel for Localhost Ports Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/quickstart.mdx Starts the minikube tunnel to bind ports 80 and 443 on your host machine. This is required for Frontline to terminate TLS and route requests to the local development environment. ```bash make tunnel ``` -------------------------------- ### Seed Local Development Database Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/quickstart.mdx Starts the database using 'make up' and then seeds it with local development data using 'make unkey dev seed local'. This prepares the database for local API requests. ```bash # Start the database make up # Seed workspace, API, and root key for local development make unkey dev seed local ``` -------------------------------- ### Run Unkey CLI with Arguments Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/quickstart.mdx Demonstrates how to pass arguments to Unkey CLI commands using the ARGS variable. This is useful for specifying ports or other flags for services. ```bash make unkey run api ARGS="--http-port=7071" ``` -------------------------------- ### Install unkey-go SDK Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/libraries/go/api.mdx This command adds the Unkey Go SDK as a dependency to your project using go get. ```bash go get github.com/unkeyed/sdks/api/go/v2@latest ``` -------------------------------- ### Start All Unkey Services with Make Source: https://github.com/unkeyed/unkey/blob/main/K8S_DEVELOPMENT.md Initiates all Unkey services locally using the Kubernetes setup. This is the primary command for bringing up the entire development environment. ```bash make k8s-up ``` -------------------------------- ### Format Code and Build Artifacts Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/quickstart.mdx Commands for maintaining code quality and building project artifacts. 'make fmt' formats the code and runs linters, while 'make build' compiles all project artifacts. ```bash # Format code and run linters make fmt # Build all artifacts make build ``` -------------------------------- ### Go Test Assertion Example Source: https://github.com/unkeyed/unkey/blob/main/AGENTS.md Example of using `testify/require` for assertions in Go unit tests, demonstrating error checking and equality comparisons. ```go func TestFeature(t *testing.T) { t.Run("scenario", func(t *testing.T) { require.NoError(t, err) require.Equal(t, expected, actual) }) } ``` -------------------------------- ### Run Unit and Integration Tests Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/quickstart.mdx Commands to execute different types of tests within the Unkey project. 'make test' runs unit tests, while 'make test-integration' runs integration tests. ```bash # Run unit tests make test # Run integration tests make test-integration ``` -------------------------------- ### Configure WorkOS Authentication Provider Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/quickstart.mdx Sets environment variables for WorkOS authentication, enabling multi-workspace scenarios. Requires client ID, API key, and a generated cookie password. ```env AUTH_PROVIDER="workos" WORKOS_CLIENT_ID= WORKOS_API_KEY= WORKOS_COOKIE_PASSWORD= ``` -------------------------------- ### Example Feature Implementation Snippets in TypeScript Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/dashboard/client-structure.mdx Provides practical examples of how different parts of a feature are implemented using TypeScript. This includes a client component export, a custom hook for queries, a server action, and a type definition. ```typescript // /feature/components/feature-list/index.tsx export function FeatureList() { // Component implementation } // /feature/hooks/queries/use-features.ts export function useFeatures() { // Hook implementation } // /feature/actions/feature-actions.ts export async function createFeature() { // Server action implementation } // /feature/types/feature.ts export interface Feature { // Type definitions } ``` -------------------------------- ### Run Unkey CLI Commands Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/quickstart.mdx Executes Unkey CLI commands with the local .env file loaded. This provides a general syntax for running various services and development tasks. ```bash # General syntax make unkey [subcommands...] # Run services make unkey run api # API server make unkey run ctrl # Control plane service make unkey run krane # K8s management service make unkey run frontline # Multi-tenant frontline server make unkey run sentinel # Deployment proxy make unkey run preflight # Pod mutation webhook # Seed data make unkey dev seed local # Seed local development data make unkey dev seed verifications # Seed verification events ``` -------------------------------- ### Development Environment Commands Source: https://github.com/unkeyed/unkey/blob/main/AGENTS.md Commands to manage the development environment, including starting and stopping Docker infrastructure and the full development environment using Tilt/minikube. ```bash make up # Start Docker infrastructure (MySQL, Redis, ClickHouse, etc.) make dev # Start full dev environment with Tilt/minikube make clean # Stop and remove all Docker services ``` -------------------------------- ### Control Unkey Services with Tilt Source: https://github.com/unkeyed/unkey/blob/main/K8S_DEVELOPMENT.md Demonstrates how to use Tilt to manage specific Unkey services. You can start combinations of services or all services using Tilt commands, providing fine-grained control over the development environment. ```bash tilt up -- --services=mysql --services=clickhouse tilt up -- --services=api --services=gw --services=ctrl tilt up -- --services=all # Stop Tilt tilt down ``` -------------------------------- ### Verify Key with Ratelimits (TypeScript) Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/quickstart/identities/shared-ratelimits.mdx Verifies an API key against specified ratelimits. This example sets up 'requests' and 'tokens' ratelimits, with the 'tokens' limit having an associated cost. It sends a POST request to the Unkey API and parses the JSON response. ```typescript const verifiedWithRatelimitsResponse = await fetch(`https://api.unkey.com/v2/keys.verifyKey`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ apiId: apiId, key: key.key, ratelimits: [ { name: "requests", }, { name: "tokens", cost: 200, }, ], }), }); const verifiedWithRatelimits = await verifiedWithRatelimitsResponse.json<{ valid: boolean; identity: { id: string; externalId: string; meta: unknown; }; }>(); ``` -------------------------------- ### Stop Unkey Development Environment Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/quickstart.mdx Shuts down the Minikube cluster and cleans up associated resources for the Unkey development environment. This command ensures a clean exit from the local development setup. ```bash make down ``` -------------------------------- ### Start HTTPS Server with TLS Configuration Source: https://github.com/unkeyed/unkey/blob/main/pkg/zen/README.md This Go code snippet demonstrates how to start a server using HTTPS by providing TLS certificate and key data. It loads the TLS configuration from files and creates a server instance with this configuration, then starts serving on a specified listener. ```go package main import ( "context" "log" "net" "github.com/unkeyed/unkey/pkg/tls" "github.com/unkeyed/unkey/pkg/zen" ) func main() { // Load TLS configuration from certificate and key files tlsConfig, err := tls.NewFromFiles("server.crt", "server.key") if err != nil { log.Fatalf("failed to load TLS configuration: %v", err) } // Create a server with TLS configuration server, err := zen.New(zen.Config{ TLS: tlsConfig, }) if err != nil { log.Fatalf("failed to create server: %v", err) } // Register routes... // Start the HTTPS server with context for graceful shutdown ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Create a listener for HTTPS listener, err := net.Listen("tcp", ":443") if err != nil { log.Fatalf("failed to create listener: %v", err) } // Start in a goroutine so you can handle shutdown signals go func() { if err := server.Serve(ctx, listener); err != nil { log.Fatalf("server error: %v", err) } }() // Set up signal handling for graceful shutdown // ... // To shut down gracefully: cancel() // This will initiate graceful shutdown } ``` -------------------------------- ### Go SDK Example: Create API Key Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/libraries/go/api.mdx This Go code snippet demonstrates how to initialize the Unkey SDK using an environment variable for authentication and then create a new API key. It includes error handling and checks for a successful response. ```go package main import ( "context" unkey "github.com/unkeyed/sdks/api/go/v2" "github.com/unkeyed/sdks/api/go/v2/models/components" "log" "os" ) func main() { ctx := context.Background() s := unkey.New( unkey.WithSecurity(os.Getenv("UNKEY_ROOT_KEY")), ) res, err := s.Apis.CreateAPI(ctx, components.V2ApisCreateAPIRequestBody{ Name: "payment-service-production", }) if err != nil { log.Fatal(err) } if res.V2ApisCreateAPIResponseBody != nil { // handle response } } ``` -------------------------------- ### Basic Cache Setup with TypeScript and MemoryStore Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/libraries/ts/cache/overview.mdx This example demonstrates setting up a basic cache with a single MemoryStore in TypeScript. It defines a User type, initializes a cache namespace for users, and shows how to set and get user data. ```typescript import { createCache, DefaultStatefulContext, Namespace } from "@unkey/cache"; import { MemoryStore } from "@unkey/cache/stores"; /** * Define the type of your data, * or perhaps generate the types from your database */ type User = { id: string; email: string; }; /** * In serverless you'd get this from the request handler * See /docs/libraries/ts/cache/overview#context */ const ctx = new DefaultStatefulContext(); const memory = new MemoryStore({ persistentMap: new Map() }); const cache = createCache({ user: new Namespace(ctx, { stores: [memory], fresh: 60_000, // Data is fresh for 60 seconds stale: 300_000, // Data is stale for 300 seconds }) }); await cache.user.set("userId", { id: "userId", email: "user@email.com" }); const user = await cache.user.get("userId") console.log(user) ``` -------------------------------- ### Create API Key with Python Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/quickstart/quickstart.mdx Creates a new API key using the Unkey SDK for Python. Instantiate the Unkey client with your root key and use the keys.create_key method. The function returns the generated API key. ```python from unkey import Unkey unkey = Unkey(root_key="your_root_key") result = unkey.keys.create_key( api_id="api_xxxx", name="My First Key" ) print(result.key) # This is the key to give to your user ``` -------------------------------- ### Create API Key Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/quickstart/quickstart.mdx This endpoint creates a new API key associated with a specific API. You need a root key for authentication. ```APIDOC ## POST /v2/keys.createKey ### Description Creates a new API key for a given API ID. This key can then be used by your users to authenticate requests. ### Method POST ### Endpoint https://api.unkey.com/v2/keys.createKey ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **apiId** (string) - Required - The ID of the API for which to create the key. - **name** (string) - Required - A human-readable name for the key. ### Request Example ```json { "apiId": "api_xxxx", "name": "My First Key" } ``` ### Response #### Success Response (200) - **meta** (object) - Request metadata. - **data** (object) - **key** (string) - The newly created API key. - **id** (string) - The ID of the created key. - **apiId** (string) - The API ID associated with the key. - **name** (string) - The name of the key. - **createdAt** (string) - Timestamp when the key was created. #### Response Example ```json { "meta": { "requestId": "req_..." }, "data": { "key": "key_abc123", "id": "key_xxxx", "apiId": "api_xxxx", "name": "My First Key", "createdAt": "2023-01-01T12:00:00Z" } } ``` ``` -------------------------------- ### Analytics API Request Example (Conceptual) Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/rfcs/0005-analytics-api.mdx Illustrates a conceptual GET request to the Unkey Analytics API to retrieve verification data. It demonstrates how to specify parameters such as start time, end time, granularity, and optional filters like apiId, externalId, and keyId. Note that specific parameter formats and available options may vary. ```http GET /v1/analytics.getVerifications?start=1678886400000&end=1678972800000&granularity=day&apiId=api_123&externalId=user_abc&keyId=key_xyz Authorization: Bearer YOUR_ROOT_KEY ``` -------------------------------- ### Create API Key with cURL Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/quickstart/quickstart.mdx Creates a new API key using the Unkey API via cURL. Requires your root key for authentication and the API ID as a parameter. Returns the newly created API key. ```bash curl -X POST https://api.unkey.com/v2/keys.createKey \ -H "Authorization: Bearer YOUR_ROOT_KEY" \ -H "Content-Type: application/json" \ -d '{ "apiId": "api_xxxx", "name": "My First Key" }' ``` -------------------------------- ### Install Unkey for Hono with Cloudflare Workers Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/cookbook/cloudflare-workers.mdx Installs the Hono framework and the Unkey Hono integration package. This setup is for using Unkey with Hono for cleaner routing in Cloudflare Workers. ```bash npm install hono @unkey/hono ``` -------------------------------- ### Install Unkey Packages (npm, pnpm, bun) Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/libraries/ts/overview.mdx Installs the necessary Unkey packages for API management and rate limiting using different package managers. ```bash npm install @unkey/api @unkey/ratelimit ``` ```bash pnpm add @unkey/api @unkey/ratelimit ``` ```bash bun add @unkey/api @unkey/ratelimit ``` -------------------------------- ### Go Test Example: User Creation Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/testing/index.mdx A basic Go test function demonstrating user creation. It uses the testify/require package for assertions, checking for errors, email equality, and non-empty user ID. ```go import ( "context" "testing" "github.com/stretchr/testify/require" ) // Assume CreateUser is defined elsewhere func TestUserCreation(t *testing.T) { ctx := context.Background() // Example context user, err := CreateUser(ctx, "alice@example.com") require.NoError(t, err) require.Equal(t, "alice@example.com", user.Email) require.NotEmpty(t, user.ID) } ``` -------------------------------- ### Start Individual Unkey Services Source: https://github.com/unkeyed/unkey/blob/main/K8S_DEVELOPMENT.md Provides commands to start specific Unkey services independently. This allows for targeted development or troubleshooting of individual components like the database, cache, or API. ```bash make start-mysql make start-clickhouse make start-redis make start-s3 make start-api make start-gw make start-ctrl ``` -------------------------------- ### Execute Go Build with BuildKit Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/architecture/workflows/github-deployments.mdx This Go code snippet demonstrates how to create a build session using Depot, acquire a remote BuildKit machine, connect to it, and execute a build. It includes defer statements for session and connection cleanup. ```go // Create Depot build session depotBuild, _ := build.NewBuild(ctx, &cliv1.CreateBuildRequest{ ProjectId: depotProjectID, }, w.registryConfig.Password) deferr func() { depotBuild.Finish(err) }() // Acquire remote BuildKit machine buildkit, _ := machine.Acquire(ctx, depotBuild.ID, depotBuild.Token, architecture) deferr buildkit.Release() // Connect to BuildKit buildClient, _ := buildkit.Connect(ctx) deferr buildClient.Close() // Execute build _, err = buildClient.Solve(ctx, nil, solverOptions, buildStatusCh) ``` -------------------------------- ### Verify API Key with Python Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/quickstart/quickstart.mdx Verifies an API key using the Unkey SDK for Python. The keys.verify_key method accepts the API key and returns a result object containing validity status, code, and key ID. ```python from unkey import Unkey unkey = Unkey(root_key="your_root_key") result = unkey.keys.verify_key(key="THE_KEY_FROM_STEP_3") if not result.valid: print("Denied:", result.code) else: print("Key ID:", result.key_id) ``` -------------------------------- ### Initialize Express App and Install Dependencies Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/quickstart/ratelimiting/express.mdx Sets up a new Express project and installs necessary packages including express, @unkey/ratelimit, and dotenv for environment variable management. This is the initial setup for an Express application with rate limiting capabilities. ```bash mkdir unkey-express-ratelimit && cd unkey-express-ratelimit npm init -y npm install express @unkey/ratelimit dotenv ``` -------------------------------- ### Go RateLimiter Method for Distributed Rate Limiting Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/documentation.mdx Provides comprehensive documentation for the 'Allow' method of a 'RateLimiter', detailing its distributed rate limiting implementation with strong consistency, lease-based algorithm, identifier usage, cost parameter, return values, and potential error conditions like ErrInvalidCost and ErrClusterUnavailable. It also notes that the method is safe for concurrent use. ```go // Allow determines whether the specified identifier can perform the requested // number of operations within the configured rate limit window. // // This method implements distributed rate limiting with strong consistency // guarantees across all nodes in the cluster. It uses a lease-based algorithm // to coordinate between nodes and ensure accurate limiting under high concurrency. // // The identifier should be a stable business identifier (user ID, API key, IP). // The cost is typically 1 for single operations, but can be higher for batch // requests. Cost must be positive or an error is returned. // // Returns (true, nil) if allowed, (false, nil) if rate limited, or (false, error) // if a system error occurs. Possible errors include ErrInvalidCost for invalid // cost values, ErrClusterUnavailable when less than 50% of cluster nodes are // reachable, context.DeadlineExceeded on timeout (default 5s), and network // errors on storage failures. // // Safe for concurrent use. If context is cancelled, no rate limit counters // are modified. func (r *RateLimiter) Allow(ctx context.Context, identifier string, cost int) (bool, error) ``` -------------------------------- ### Verify API Key Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/quickstart/quickstart.mdx This endpoint verifies the validity of an API key. It's used on every API request to ensure the key is active and authorized. ```APIDOC ## POST /v2/keys.verifyKey ### Description Verifies if a given API key is valid and authorized to access resources. This is the primary endpoint for securing your API. ### Method POST ### Endpoint https://api.unkey.com/v2/keys.verifyKey ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **key** (string) - Required - The API key to verify. ### Request Example ```json { "key": "THE_KEY_FROM_STEP_3" } ``` ### Response #### Success Response (200) - **meta** (object) - Request metadata. - **data** (object) - **valid** (boolean) - Indicates if the key is valid. - **code** (string) - A status code (e.g., `VALID`, `NOT_FOUND`, `RATE_LIMITED`). - **keyId** (string) - The unique identifier of the key. - **name** (string?) - The human-readable name of the key. - **meta** (object?) - Custom metadata associated with the key. - **expires** (number?) - Unix timestamp (in milliseconds) of key expiration. - **credits** (number?) - Remaining uses if usage limits are set. - **enabled** (boolean) - Whether the key is currently enabled. - **roles** (string[]?) - Roles assigned to the key. - **permissions** (string[]?) - Specific permissions granted to the key. - **identity** (object?) - Identity information if an `externalId` was set during key creation. - **ratelimits** (object[]?) - Current state of rate limits applied to the key. #### Response Example ```json { "meta": { "requestId": "req_..." }, "data": { "valid": true, "code": "VALID", "keyId": "key_xxxx", "name": "My First Key", "expires": 1735689600000, "enabled": true, "roles": ["admin"], "permissions": ["read:data", "write:data"] } } ``` ``` -------------------------------- ### Configure Stripe Billing Integration Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/quickstart.mdx Sets the environment variable for Stripe integration, enabling multi-user workspaces. Requires your Stripe secret key. ```env STRIPE_SECRET_KEY= ``` -------------------------------- ### Usage Analytics - All Outcomes in a Single Row Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/analytics/query-examples.mdx Get all verification outcomes in a single row with individual columns for each outcome type over the last 30 days. ```APIDOC ## Usage Analytics - All Outcomes in a Single Row ### Description Get all verification outcomes in one row with individual columns for each outcome type over the last 30 days. ### Method POST ### Endpoint https://api.unkey.com/v2/analytics.getVerifications ### Parameters #### Request Body - **query** (string) - Required - The SQL query to execute, formatted as a single-line JSON string. ### Request Example ```json { "query": "SELECT sumIf(count, outcome = 'VALID') AS valid, sumIf(count, outcome = 'RATE_LIMITED') AS rateLimited, sumIf(count, outcome = 'INVALID') AS invalid, sumIf(count, outcome = 'NOT_FOUND') AS notFound, sumIf(count, outcome = 'FORBIDDEN') AS forbidden, sumIf(count, outcome = 'USAGE_EXCEEDED') AS usageExceeded, sumIf(count, outcome = 'UNAUTHORIZED') AS unauthorized, sumIf(count, outcome = 'DISABLED') AS disabled, sumIf(count, outcome = 'INSUFFICIENT_PERMISSIONS') AS insufficientPermissions, sumIf(count, outcome = 'EXPIRED') AS expired, SUM(count) AS total FROM key_verifications_per_day_v1 WHERE time >= now() - INTERVAL 30 DAY" } ``` ### Response #### Success Response (200) - **data** (object) - The result of the SQL query. #### Response Example ```json { "data": [ { "valid": 40000, "rateLimited": 5000, "invalid": 1000, "notFound": 500, "forbidden": 200, "usageExceeded": 100, "unauthorized": 50, "disabled": 20, "insufficientPermissions": 10, "expired": 5, "total": 46885 } ] } ``` ``` -------------------------------- ### Go RateLimiter Method for Request Allowance (Insufficient) Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/documentation.mdx Presents an example of insufficient documentation for the 'Allow' method of a 'RateLimiter', highlighting the lack of detail regarding distributed coordination, error conditions, and return value semantics compared to a comprehensive version. ```go // Allow checks if a request is allowed. func (r *RateLimiter) Allow(ctx context.Context, identifier string, cost int) (bool, error) ``` -------------------------------- ### Create API Key with TypeScript Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/quickstart/quickstart.mdx Creates a new API key using the Unkey SDK for TypeScript. This method requires initializing the Unkey client with your root key and then calling the keys.create method. It outputs the generated API key. ```typescript import { Unkey } from "@unkey/api"; const unkey = new Unkey({ rootKey: process.env.UNKEY_ROOT_KEY }); try { const { meta, data } = await unkey.keys.create({ apiId: "api_xxxx", name: "My First Key", }); console.log(data.key); // This is the key to give to your user } catch (err) { console.error(err); } ``` -------------------------------- ### Bash Request Example: Get Key Details (Error) Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/errors/unkey/data/key_not_found.mdx This bash script demonstrates a cURL request to the Unkey API to retrieve details for a specific key. This example is designed to trigger the 'key_not_found' error by using a non-existent key ID. ```bash # Attempting to get details for a non-existent key curl -X POST https://api.unkey.com/v2/keys.getKey \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "keyId": "key_nonexistent" }' ``` -------------------------------- ### SQL Examples: Valid Analytics Queries in Unkey Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/errors/user/bad_request/invalid_analytics_query_type.mdx Provides examples of valid SQL SELECT queries for Unkey analytics. These queries demonstrate how to count verifications by outcome, get hourly verification rates, and find the most active APIs, all adhering to the read-only nature of analytics. ```sql -- ✓ Count verifications by outcome SELECT outcome, COUNT(*) as total FROM key_verifications_v1 WHERE time >= now() - INTERVAL 1 DAY GROUP BY outcome ``` ```sql -- ✓ Get hourly verification rates SELECT toStartOfHour(time) as hour, COUNT(*) as verifications FROM key_verifications_v1 WHERE time >= now() - INTERVAL 24 HOUR GROUP BY hour ORDER BY hour ``` ```sql -- ✓ Find most active APIs SELECT api_id, COUNT(*) as requests FROM key_verifications_v1 WHERE time >= now() - INTERVAL 7 DAY GROUP BY api_id ORDER BY requests DESC LIMIT 10 ``` -------------------------------- ### Package Documentation Structure (Go) Source: https://github.com/unkeyed/unkey/blob/main/web/apps/engineering/content/docs/contributing/documentation.mdx Demonstrates the standard structure for a `doc.go` file, which includes a package comment, package declaration, and organized sections using markdown headers. It provides a concrete example of documenting a rate limiting package, explaining its purpose, key types, usage, and error handling. ```go // Package ratelimit implements distributed rate limiting with lease-based coordination. // // The package uses a two-phase commit protocol to ensure consistency across // multiple nodes in a cluster. Rate limits are enforced through sliding time // windows with configurable burst allowances. // // This implementation was chosen over simpler approaches because we need // strong consistency guarantees for billing and security use cases. // // # Key Types // // The main entry point is [RateLimiter], which provides the [RateLimiter.Allow] // method for checking rate limits. Configuration is handled through [Config]. // // # Usage // // Basic rate limiting: // // cfg := ratelimit.Config{Window: time.Minute, Limit: 100} // limiter := ratelimit.New(cfg) // allowed, err := limiter.Allow(ctx, "user:123", 1) // if err != nil { // // Handle system error // } // if !allowed { // // Rate limited - reject request // } // // # Error Handling // // The package distinguishes between rate limiting (expected behavior) and // system errors (unexpected failures). See [ErrRateLimited] and [ErrClusterUnavailable]. package ratelimit ``` -------------------------------- ### POST /v2/analytics.getVerifications Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/analytics/getting-started.mdx This endpoint allows you to run SQL queries against your Unkey analytics data. You can retrieve information such as total verifications, breakdown by outcome, and top users by usage. ```APIDOC ## POST /v2/analytics.getVerifications ### Description This endpoint allows you to run SQL queries against your Unkey analytics data. You can retrieve information such as total verifications, breakdown by outcome, and top users by usage. ### Method POST ### Endpoint https://api.unkey.com/v2/analytics.getVerifications ### Parameters #### Request Body - **query** (string) - Required - The SQL query to execute against the analytics data. ### Request Example ```json { "query": "SELECT SUM(count) as total FROM key_verifications_per_day_v1 WHERE time >= now() - INTERVAL 7 DAY" } ``` ### Response #### Success Response (200) - **meta** (object) - Contains metadata about the request, including `requestId`. - **data** (array) - An array of objects, where each object contains fields from your SELECT clause. #### Response Example ```json { "meta": { "requestId": "req_xxx" }, "data": [ { "outcome": "VALID", "count": 1234 }, { "outcome": "RATE_LIMITED", "count": 56 }, { "outcome": "USAGE_EXCEEDED", "count": 12 } ] } ``` ``` -------------------------------- ### Run Next.js Development Server (Bash) Source: https://github.com/unkeyed/unkey/blob/main/web/apps/dashboard/README.md Commands to start the Next.js development server using npm, yarn, or pnpm. This allows for live preview and auto-updates during development. ```bash npm run dev # or yarn dev # or pnpm dev ``` -------------------------------- ### Project README Markdown Example with Unkey Configuration Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/ai-code-gen/cursor.mdx This Markdown example shows how to document Unkey-specific configurations within a project's README file. It includes sections for environment variables, API routes, and rate limiting tiers, providing context for developers and Cursor's AI. ```markdown # My Project This project uses Unkey for API authentication and ratelimiting. ## Environment Variables - `UNKEY_ROOT_KEY`: Your Unkey root key - `UNKEY_API_ID`: Your API ID from the Unkey dashboard ## API Routes - `/api/protected` - Requires valid API key - `/api/keys` - Manage API keys (admin only) ## Rate Limiting - Free tier: 100 requests/hour - Pro tier: 1000 requests/hour ``` -------------------------------- ### Synchronous Unkey SDK Usage Example Source: https://github.com/unkeyed/unkey/blob/main/web/apps/docs/libraries/py/api.mdx Provides an example of how to use the Unkey Python SDK for synchronous API calls. It demonstrates initializing the SDK client with a bearer token and making a request to create an API. ```python # Synchronous Example from unkey.py import Unkey with Unkey( root_key="", ) as unkey: res = unkey.apis.create_api(name="payment-service-production") # Handle response print(res) ```