Skip to content

docs: update references to v2#3747

Merged
chronark merged 10 commits intomainfrom
docs-v2
Aug 8, 2025
Merged

docs: update references to v2#3747
chronark merged 10 commits intomainfrom
docs-v2

Conversation

@chronark
Copy link
Collaborator

@chronark chronark commented Aug 7, 2025

This addresses many small instances where we still references v1
it's not complete yet unfortunately, but a first start

Summary by CodeRabbit

  • Documentation
    • Updated all API endpoint URLs and examples to use the new https://api.unkey.com/v2/ base and version, replacing deprecated v1 endpoints across documentation.
    • Adjusted example request methods, payload structures, and removed or renamed fields to align with v2 API changes.
    • Added notes clarifying current API version support for analytics and migration endpoints.
    • Removed outdated or deprecated documentation sections and examples.
    • Updated navigation labels, redirects, and repository links for improved clarity and accuracy.

@vercel
Copy link

vercel bot commented Aug 7, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
dashboard ⬜️ Ignored (Inspect) Visit Preview Aug 7, 2025 9:17am
engineering ⬜️ Ignored (Inspect) Visit Preview Aug 7, 2025 9:17am

@changeset-bot
Copy link

changeset-bot bot commented Aug 7, 2025

⚠️ No Changeset found

Latest commit: a6d6752

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 7, 2025

Warning

Rate limit exceeded

@chronark has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 10 minutes and 35 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between f35696f and a6d6752.

📒 Files selected for processing (1)
  • apps/docs/apis/features/authorization/example.mdx (3 hunks)
📝 Walkthrough

Walkthrough

This update revises documentation throughout the codebase to reflect a transition from v1 to v2 of the Unkey API. It updates API endpoint URLs, request formats, and payload structures in code samples, removes outdated documentation, and adds informational notes about the current availability of analytics and migration endpoints. Navigation and reference links are also updated accordingly.

Changes

Cohort / File(s) Change Summary
Analytics & Migration Availability Notes
apps/docs/analytics/overview.mdx, apps/docs/analytics/quickstarts.mdx, apps/docs/migrations/introduction.mdx, apps/docs/migrations/keys.mdx
Added notes clarifying analytics and migration endpoints are only available in v1 API, with v2 support planned.
API Endpoint URL & Version Updates
apps/docs/apis/features/authorization/example.mdx, apps/docs/apis/features/authorization/roles-and-permissions.mdx, apps/docs/apis/features/enabled.mdx, apps/docs/apis/features/refill.mdx, apps/docs/apis/features/temp-keys.mdx, apps/docs/apis/features/ratelimiting/overview.mdx, apps/docs/apis/introduction.mdx, apps/docs/api-reference/v2/auth.mdx, apps/docs/errors/unkey/application/protected_resource.mdx, apps/docs/errors/unkey/application/service_unavailable.mdx, apps/docs/errors/unkey/application/unexpected_error.mdx, apps/docs/errors/unkey/authentication/key_not_found.mdx, apps/docs/errors/unkey/authentication/malformed.mdx, apps/docs/errors/unkey/authentication/missing.mdx, apps/docs/errors/unkey/authorization/insufficient_permissions.mdx, apps/docs/errors/unkey/authorization/key_disabled.mdx, apps/docs/errors/unkey/authorization/workspace_disabled.mdx, apps/docs/errors/unkey/data/api_not_found.mdx, apps/docs/errors/unkey/data/identity_already_exists.mdx, apps/docs/errors/unkey/data/identity_not_found.mdx, apps/docs/errors/unkey/data/key_not_found.mdx, apps/docs/security/recovering-keys.mdx, apps/docs/libraries/ts/nextjs.mdx
Updated all example API endpoint URLs and versions from v1 (api.unkey.dev) to v2 (api.unkey.com).
Request Payload and Structure Adjustments
apps/docs/apis/features/analytics.mdx, apps/docs/apis/features/authorization/verifying.mdx, apps/docs/apis/features/remaining.mdx, apps/docs/quickstart/identities/shared-ratelimits.mdx, apps/docs/security/recovering-keys.mdx
Modified example request payloads: removed apiId fields, changed flat fields to nested objects (e.g., remaining to credits), adjusted HTTP methods (GET to POST), and updated request body structures.
Documentation File Removals
apps/docs/apis/features/ratelimiting/modes.mdx
Removed documentation describing rate limiting modes.
Navigation and Reference Updates
apps/docs/docs.json, apps/docs/libraries/ts/hono.mdx
Updated navigation structure, deprecated v1 API reference label, updated redirect paths, and changed GitHub/documentation links.
Error Documentation Example Removals & Updates
apps/docs/errors/unkey/data/key_auth_not_found.mdx, apps/docs/errors/unkey/data/permission_not_found.mdx, apps/docs/errors/unkey/data/role_not_found.mdx, apps/docs/errors/unkey/data/workspace_not_found.mdx
Removed outdated or redundant example requests and updated remaining examples to use new API endpoints, HTTP methods, and payloads.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Docs
    participant UnkeyAPIv2

    Client->>Docs: Read API usage example
    Docs-->>Client: Show v2 endpoint, updated payload
    Client->>UnkeyAPIv2: Send request (POST, new URL, new body)
    UnkeyAPIv2-->>Client: Respond with result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

🕹️ oss.gg

Suggested reviewers

  • perkinsjr
  • mcstepp
  • MichaelUnkey
  • ogzhanolguncu
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch docs-v2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions
Copy link
Contributor

github-actions bot commented Aug 7, 2025

Thank you for following the naming conventions for pull request titles! 🙏

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🔭 Outside diff range comments (5)
apps/docs/apis/features/enabled.mdx (1)

19-26: Typo fix & style nit

There’s a small misspelling a few lines above the changed code that’s worth cleaning up while you’re here.

-Let's disable a key temperarily blocking access with that key. 
+Let's disable a key temporarily, blocking access with that key. 

Everything else about the v2 URL updates looks correct.

Also applies to: 32-36

apps/docs/apis/features/analytics.mdx (1)

64-71: Update tag example to avoid “v1” in path

Minor: the tag value path=/v1/my-resource/123 still hard-codes v1, which may confuse readers right after showcasing a v2 endpoint. Consider changing to /v2/… or a neutral placeholder.

apps/docs/errors/unkey/application/protected_resource.mdx (1)

37-43: Multiple lingering v1 endpoints detected in docs – please update to v2

The migration to /v2 isn’t complete. Running

rg -n --no-heading --ignore-case -e 'https://api\.unkey\.com/v1' -e 'https://api\.unkey\.dev/v1' apps/docs

returned numerous hits. At a minimum, update or remove all occurrences in:

  • apps/docs/migrations/keys.mdx (lines 61, 93)
  • apps/docs/libraries/ex/overview.mdx (lines 29, 48)
  • apps/docs/analytics/overview.mdx (lines 40, 66)
  • all files under apps/docs/api-reference/v1/…
  • apps/docs/analytics/quickstarts.mdx (multiple lines)

Please replace these v1 URLs with their v2 equivalents (or remove legacy examples) to complete the migration.

apps/docs/errors/unkey/data/audit_log_not_found.mdx (2)

39-44: Add explicit Content-Type header for JSON payloads

Without the Content-Type: application/json header cURL defaults to application/x-www-form-urlencoded, which can cause the API to reject or mis-interpret the body.
Same applies to the list-logs example below.

 curl -X POST https://api.unkey.com/v2/audit.getLog \
   -H "Authorization: Bearer unkey_YOUR_API_KEY" \
+  -H "Content-Type: application/json" \
   -d '{
     "logId": "log_nonexistent"
   }'

58-63: Repeat header omission

For consistency add the Content-Type header here as well.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9038046 and a3b7e4e.

📒 Files selected for processing (39)
  • apps/docs/analytics/overview.mdx (1 hunks)
  • apps/docs/analytics/quickstarts.mdx (1 hunks)
  • apps/docs/api-reference/v2/auth.mdx (1 hunks)
  • apps/docs/apis/features/analytics.mdx (1 hunks)
  • apps/docs/apis/features/authorization/example.mdx (1 hunks)
  • apps/docs/apis/features/authorization/roles-and-permissions.mdx (1 hunks)
  • apps/docs/apis/features/authorization/verifying.mdx (3 hunks)
  • apps/docs/apis/features/enabled.mdx (2 hunks)
  • apps/docs/apis/features/ratelimiting/modes.mdx (0 hunks)
  • apps/docs/apis/features/ratelimiting/overview.mdx (8 hunks)
  • apps/docs/apis/features/refill.mdx (2 hunks)
  • apps/docs/apis/features/remaining.mdx (3 hunks)
  • apps/docs/apis/features/temp-keys.mdx (1 hunks)
  • apps/docs/apis/introduction.mdx (1 hunks)
  • apps/docs/docs.json (3 hunks)
  • apps/docs/errors/unkey/application/protected_resource.mdx (1 hunks)
  • apps/docs/errors/unkey/application/service_unavailable.mdx (2 hunks)
  • apps/docs/errors/unkey/application/unexpected_error.mdx (1 hunks)
  • apps/docs/errors/unkey/authentication/key_not_found.mdx (2 hunks)
  • apps/docs/errors/unkey/authentication/malformed.mdx (2 hunks)
  • apps/docs/errors/unkey/authentication/missing.mdx (2 hunks)
  • apps/docs/errors/unkey/authorization/insufficient_permissions.mdx (2 hunks)
  • apps/docs/errors/unkey/authorization/key_disabled.mdx (2 hunks)
  • apps/docs/errors/unkey/authorization/workspace_disabled.mdx (1 hunks)
  • apps/docs/errors/unkey/data/api_not_found.mdx (2 hunks)
  • apps/docs/errors/unkey/data/audit_log_not_found.mdx (2 hunks)
  • apps/docs/errors/unkey/data/identity_already_exists.mdx (1 hunks)
  • apps/docs/errors/unkey/data/identity_not_found.mdx (2 hunks)
  • apps/docs/errors/unkey/data/key_auth_not_found.mdx (1 hunks)
  • apps/docs/errors/unkey/data/key_not_found.mdx (2 hunks)
  • apps/docs/errors/unkey/data/permission_not_found.mdx (1 hunks)
  • apps/docs/errors/unkey/data/role_not_found.mdx (1 hunks)
  • apps/docs/errors/unkey/data/workspace_not_found.mdx (1 hunks)
  • apps/docs/libraries/ts/hono.mdx (3 hunks)
  • apps/docs/libraries/ts/nextjs.mdx (1 hunks)
  • apps/docs/migrations/introduction.mdx (1 hunks)
  • apps/docs/migrations/keys.mdx (1 hunks)
  • apps/docs/quickstart/identities/shared-ratelimits.mdx (6 hunks)
  • apps/docs/security/recovering-keys.mdx (2 hunks)
💤 Files with no reviewable changes (1)
  • apps/docs/apis/features/ratelimiting/modes.mdx
🧰 Additional context used
📓 Path-based instructions (1)
**/migrations/**/*

📄 CodeRabbit Inference Engine (CLAUDE.md)

Use Drizzle migrations for database changes, not manual SQL

Files:

  • apps/docs/migrations/keys.mdx
  • apps/docs/migrations/introduction.mdx
🧠 Learnings (43)
📓 Common learnings
Learnt from: Flo4604
PR: unkeyed/unkey#3421
File: go/apps/api/openapi/openapi.yaml:196-200
Timestamp: 2025-07-03T05:58:10.699Z
Learning: In the Unkey codebase, OpenAPI 3.1 is used, which allows sibling keys (such as `description`) alongside `$ref` in schema objects. Do not flag this as an error in future reviews.
Learnt from: MichaelUnkey
PR: unkeyed/unkey#3173
File: apps/docs/security/delete-protection.mdx:32-36
Timestamp: 2025-04-22T17:33:28.162Z
Learning: In the Unkey dashboard UI for delete protection, the button/link to initiate the process is labeled "Disable Delete Protection" while the confirmation button is labeled "Disable API Delete Protection". The documentation should maintain these different labels to match the actual UI.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3321
File: apps/dashboard/lib/trpc/routers/authorization/roles/keys/schema-with-helpers.ts:5-8
Timestamp: 2025-06-18T12:28:10.449Z
Learning: In the unkey dashboard application, API validation for pagination limits is controlled at the UI level rather than requiring additional server-side validation, as the APIs are internal and protected by UI logic.
Learnt from: MichaelUnkey
PR: unkeyed/unkey#3173
File: apps/docs/security/delete-protection.mdx:21-24
Timestamp: 2025-04-22T17:34:04.438Z
Learning: In the Unkey dashboard UI for enabling delete protection, the button/link to initiate the process is labeled "Enable Delete Protection" while the confirmation button is labeled "Enable API Delete Protection". The documentation should maintain these different labels to match the actual UI.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3661
File: go/apps/api/routes/v2_identities_update_identity/handler.go:115-119
Timestamp: 2025-07-28T11:47:43.144Z
Learning: The v2 update identity endpoint (go/apps/api/routes/v2_identities_update_identity/handler.go) intentionally uses `ExternalId` field instead of the unified `Identity` field used in other v2 identity endpoints. This is because the update endpoint needs to both find by externalId and potentially update the externalId value, making the specific field name more appropriate than the generic `Identity` field.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3242
File: apps/dashboard/app/(app)/apis/[apiId]/_overview/components/table/components/override-indicator.tsx:50-65
Timestamp: 2025-05-15T16:26:08.666Z
Learning: In the Unkey dashboard, Next.js router (router.push) should be used for client-side navigation instead of window.location.href to preserve client state and enable smoother transitions between pages.
📚 Learning: in the `v1/keys.updatekey` endpoint, the server validates the refill configuration before checking i...
Learnt from: MichaelUnkey
PR: unkeyed/unkey#2114
File: apps/api/src/routes/v1_keys_updateKey.error.test.ts:0-0
Timestamp: 2024-09-27T15:20:05.475Z
Learning: In the `v1/keys.updateKey` endpoint, the server validates the refill configuration before checking if the key exists. Therefore, tests can assert validation errors without needing to create the key first.

Applied to files:

  • apps/docs/apis/features/refill.mdx
  • apps/docs/errors/unkey/authorization/insufficient_permissions.mdx
  • apps/docs/api-reference/v2/auth.mdx
  • apps/docs/errors/unkey/application/unexpected_error.mdx
  • apps/docs/apis/features/enabled.mdx
  • apps/docs/errors/unkey/authentication/key_not_found.mdx
  • apps/docs/errors/unkey/authorization/key_disabled.mdx
  • apps/docs/apis/features/authorization/verifying.mdx
  • apps/docs/errors/unkey/authentication/missing.mdx
  • apps/docs/apis/features/remaining.mdx
  • apps/docs/apis/features/authorization/example.mdx
  • apps/docs/errors/unkey/data/key_auth_not_found.mdx
  • apps/docs/errors/unkey/application/service_unavailable.mdx
  • apps/docs/apis/features/authorization/roles-and-permissions.mdx
  • apps/docs/apis/features/ratelimiting/overview.mdx
  • apps/docs/errors/unkey/data/key_not_found.mdx
📚 Learning: in the unkey codebase, openapi 3.1 is used, which allows sibling keys (such as `description`) alongs...
Learnt from: Flo4604
PR: unkeyed/unkey#3421
File: go/apps/api/openapi/openapi.yaml:196-200
Timestamp: 2025-07-03T05:58:10.699Z
Learning: In the Unkey codebase, OpenAPI 3.1 is used, which allows sibling keys (such as `description`) alongside `$ref` in schema objects. Do not flag this as an error in future reviews.

Applied to files:

  • apps/docs/apis/features/refill.mdx
  • apps/docs/migrations/keys.mdx
  • apps/docs/errors/unkey/authorization/insufficient_permissions.mdx
  • apps/docs/errors/unkey/application/unexpected_error.mdx
  • apps/docs/apis/features/enabled.mdx
  • apps/docs/errors/unkey/authentication/key_not_found.mdx
  • apps/docs/errors/unkey/application/protected_resource.mdx
  • apps/docs/errors/unkey/authorization/key_disabled.mdx
  • apps/docs/libraries/ts/hono.mdx
  • apps/docs/errors/unkey/authentication/malformed.mdx
  • apps/docs/apis/features/authorization/verifying.mdx
  • apps/docs/security/recovering-keys.mdx
  • apps/docs/errors/unkey/authentication/missing.mdx
  • apps/docs/errors/unkey/authorization/workspace_disabled.mdx
  • apps/docs/apis/features/remaining.mdx
  • apps/docs/apis/features/authorization/example.mdx
  • apps/docs/errors/unkey/data/key_auth_not_found.mdx
  • apps/docs/errors/unkey/application/service_unavailable.mdx
  • apps/docs/apis/features/authorization/roles-and-permissions.mdx
  • apps/docs/errors/unkey/data/key_not_found.mdx
  • apps/docs/errors/unkey/data/api_not_found.mdx
📚 Learning: when implementing endpoints that require a key, avoid sending the key as part of the url. use post m...
Learnt from: chronark
PR: unkeyed/unkey#2159
File: apps/api/src/routes/v1_keys_getWhoAmI.ts:12-13
Timestamp: 2024-10-08T15:33:04.290Z
Learning: When implementing endpoints that require a key, avoid sending the key as part of the URL. Use POST methods with the key in the request body instead, as URLs get logged and could leak sensitive information.

Applied to files:

  • apps/docs/apis/features/refill.mdx
  • apps/docs/errors/unkey/authorization/insufficient_permissions.mdx
  • apps/docs/api-reference/v2/auth.mdx
  • apps/docs/errors/unkey/application/unexpected_error.mdx
  • apps/docs/apis/introduction.mdx
  • apps/docs/errors/unkey/data/audit_log_not_found.mdx
  • apps/docs/apis/features/enabled.mdx
  • apps/docs/errors/unkey/authentication/key_not_found.mdx
  • apps/docs/errors/unkey/authorization/key_disabled.mdx
  • apps/docs/errors/unkey/authentication/malformed.mdx
  • apps/docs/security/recovering-keys.mdx
  • apps/docs/errors/unkey/authentication/missing.mdx
  • apps/docs/apis/features/remaining.mdx
  • apps/docs/apis/features/authorization/example.mdx
  • apps/docs/errors/unkey/application/service_unavailable.mdx
  • apps/docs/apis/features/authorization/roles-and-permissions.mdx
  • apps/docs/apis/features/ratelimiting/overview.mdx
  • apps/docs/errors/unkey/data/identity_not_found.mdx
  • apps/docs/errors/unkey/data/key_not_found.mdx
  • apps/docs/errors/unkey/data/api_not_found.mdx
  • apps/docs/apis/features/temp-keys.mdx
📚 Learning: in the unkey api openapi schema, the permissions query regex for the verifykey endpoint intentionall...
Learnt from: chronark
PR: unkeyed/unkey#3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via `\s`. Do not flag this as an error in future reviews.

Applied to files:

  • apps/docs/apis/features/refill.mdx
  • apps/docs/errors/unkey/authorization/insufficient_permissions.mdx
  • apps/docs/apis/features/enabled.mdx
  • apps/docs/errors/unkey/authorization/key_disabled.mdx
  • apps/docs/apis/features/authorization/verifying.mdx
  • apps/docs/errors/unkey/authorization/workspace_disabled.mdx
  • apps/docs/apis/features/authorization/example.mdx
  • apps/docs/apis/features/authorization/roles-and-permissions.mdx
📚 Learning: in `apps/api/src/routes/v1_keys_updatekey.ts`, the code intentionally handles `externalid` and `owne...
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.

Applied to files:

  • apps/docs/migrations/keys.mdx
  • apps/docs/errors/unkey/data/identity_already_exists.mdx
  • apps/docs/apis/features/enabled.mdx
  • apps/docs/errors/unkey/authorization/key_disabled.mdx
  • apps/docs/libraries/ts/hono.mdx
  • apps/docs/apis/features/authorization/verifying.mdx
  • apps/docs/security/recovering-keys.mdx
  • apps/docs/apis/features/authorization/example.mdx
  • apps/docs/errors/unkey/data/key_auth_not_found.mdx
  • apps/docs/apis/features/authorization/roles-and-permissions.mdx
  • apps/docs/errors/unkey/data/identity_not_found.mdx
  • apps/docs/errors/unkey/data/key_not_found.mdx
  • apps/docs/quickstart/identities/shared-ratelimits.mdx
  • apps/docs/errors/unkey/data/api_not_found.mdx
  • apps/docs/apis/features/temp-keys.mdx
📚 Learning: in the unkey codebase, input validation for api endpoints is primarily handled through openapi schem...
Learnt from: Flo4604
PR: unkeyed/unkey#2955
File: go/apps/api/routes/v2_identities_create_identity/handler.go:162-202
Timestamp: 2025-03-19T09:25:59.751Z
Learning: In the Unkey codebase, input validation for API endpoints is primarily handled through OpenAPI schema validation, which occurs before requests reach the handler code. For example, in the identities.createIdentity endpoint, minimum values for ratelimit duration and limit are defined in the OpenAPI schema rather than duplicating these checks in the handler.

Applied to files:

  • apps/docs/migrations/keys.mdx
  • apps/docs/errors/unkey/authorization/insufficient_permissions.mdx
  • apps/docs/api-reference/v2/auth.mdx
  • apps/docs/errors/unkey/application/unexpected_error.mdx
  • apps/docs/errors/unkey/data/identity_already_exists.mdx
  • apps/docs/apis/introduction.mdx
  • apps/docs/apis/features/authorization/verifying.mdx
  • apps/docs/migrations/introduction.mdx
  • apps/docs/apis/features/remaining.mdx
  • apps/docs/errors/unkey/application/service_unavailable.mdx
  • apps/docs/apis/features/ratelimiting/overview.mdx
  • apps/docs/errors/unkey/data/identity_not_found.mdx
  • apps/docs/quickstart/identities/shared-ratelimits.mdx
📚 Learning: in the unkey dashboard application, api validation for pagination limits is controlled at the ui lev...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3321
File: apps/dashboard/lib/trpc/routers/authorization/roles/keys/schema-with-helpers.ts:5-8
Timestamp: 2025-06-18T12:28:10.449Z
Learning: In the unkey dashboard application, API validation for pagination limits is controlled at the UI level rather than requiring additional server-side validation, as the APIs are internal and protected by UI logic.

Applied to files:

  • apps/docs/migrations/keys.mdx
  • apps/docs/errors/unkey/application/protected_resource.mdx
  • apps/docs/migrations/introduction.mdx
  • apps/docs/apis/features/ratelimiting/overview.mdx
  • apps/docs/errors/unkey/data/api_not_found.mdx
📚 Learning: the codebase for unkey allows the use of modern javascript features like array.prototype.tosorted() ...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3242
File: apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/[keyId]/components/table/hooks/use-logs-query.ts:228-231
Timestamp: 2025-05-15T16:21:50.911Z
Learning: The codebase for Unkey allows the use of modern JavaScript features like Array.prototype.toSorted() even though they may not be supported in all browsers.

Applied to files:

  • apps/docs/migrations/keys.mdx
📚 Learning: for identity deletion operations in the unkey api, identityid takes precedence over externalid when ...
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.

Applied to files:

  • apps/docs/migrations/keys.mdx
  • apps/docs/errors/unkey/data/identity_already_exists.mdx
  • apps/docs/errors/unkey/application/protected_resource.mdx
  • apps/docs/errors/unkey/authentication/missing.mdx
  • apps/docs/errors/unkey/data/key_auth_not_found.mdx
  • apps/docs/apis/features/ratelimiting/overview.mdx
  • apps/docs/errors/unkey/data/identity_not_found.mdx
  • apps/docs/errors/unkey/data/key_not_found.mdx
  • apps/docs/quickstart/identities/shared-ratelimits.mdx
  • apps/docs/apis/features/temp-keys.mdx
📚 Learning: in the unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` di...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.

Applied to files:

  • apps/docs/errors/unkey/data/workspace_not_found.mdx
  • apps/docs/errors/unkey/authorization/workspace_disabled.mdx
📚 Learning: when querying or updating namespaces in the unkey dashboard, always scope the operations to the curr...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: When querying or updating namespaces in the Unkey dashboard, always scope the operations to the current workspace using `eq(table.workspaceId, ctx.workspace.id)` to prevent cross-workspace access.

Applied to files:

  • apps/docs/errors/unkey/data/workspace_not_found.mdx
  • apps/docs/errors/unkey/authorization/workspace_disabled.mdx
  • apps/docs/errors/unkey/data/permission_not_found.mdx
  • apps/docs/errors/unkey/data/role_not_found.mdx
📚 Learning: when typing the `workspace` parameter in functions like `createworkspacenavigation`, prefer importin...
Learnt from: chronark
PR: unkeyed/unkey#2180
File: apps/dashboard/lib/constants/workspace-navigations.tsx:56-118
Timestamp: 2024-10-04T20:44:38.489Z
Learning: When typing the `workspace` parameter in functions like `createWorkspaceNavigation`, prefer importing the `Workspace` type from the database module and picking the necessary keys (e.g., `features`) instead of redefining the interface.

Applied to files:

  • apps/docs/errors/unkey/data/workspace_not_found.mdx
📚 Learning: in the unkey codebase, ogzhanolguncu prefers to keep invariant checks that throw errors for cases th...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3480
File: apps/dashboard/app/new-2/hooks/use-workspace-step.tsx:47-79
Timestamp: 2025-07-09T11:35:51.724Z
Learning: In the Unkey codebase, ogzhanolguncu prefers to keep invariant checks that throw errors for cases that shouldn't happen in normal operation (like null workspace ID checks), rather than adding graceful error handling code for edge cases that would only occur if someone tampers with the actual flow.

Applied to files:

  • apps/docs/errors/unkey/data/workspace_not_found.mdx
  • apps/docs/errors/unkey/authorization/workspace_disabled.mdx
📚 Learning: in the unkey dashboard ui for enabling delete protection, the button/link to initiate the process is...
Learnt from: MichaelUnkey
PR: unkeyed/unkey#3173
File: apps/docs/security/delete-protection.mdx:21-24
Timestamp: 2025-04-22T17:34:04.438Z
Learning: In the Unkey dashboard UI for enabling delete protection, the button/link to initiate the process is labeled "Enable Delete Protection" while the confirmation button is labeled "Enable API Delete Protection". The documentation should maintain these different labels to match the actual UI.

Applied to files:

  • apps/docs/errors/unkey/authorization/insufficient_permissions.mdx
  • apps/docs/apis/features/enabled.mdx
  • apps/docs/errors/unkey/application/protected_resource.mdx
  • apps/docs/errors/unkey/authorization/key_disabled.mdx
  • apps/docs/errors/unkey/authentication/malformed.mdx
  • apps/docs/apis/features/authorization/verifying.mdx
  • apps/docs/security/recovering-keys.mdx
  • apps/docs/errors/unkey/authentication/missing.mdx
  • apps/docs/apis/features/authorization/example.mdx
  • apps/docs/errors/unkey/application/service_unavailable.mdx
  • apps/docs/apis/features/authorization/roles-and-permissions.mdx
  • apps/docs/apis/features/ratelimiting/overview.mdx
  • apps/docs/errors/unkey/data/key_not_found.mdx
  • apps/docs/docs.json
  • apps/docs/errors/unkey/data/api_not_found.mdx
  • apps/docs/apis/features/temp-keys.mdx
📚 Learning: in the unkey dashboard ui for delete protection, the button/link to initiate the process is labeled ...
Learnt from: MichaelUnkey
PR: unkeyed/unkey#3173
File: apps/docs/security/delete-protection.mdx:32-36
Timestamp: 2025-04-22T17:33:28.162Z
Learning: In the Unkey dashboard UI for delete protection, the button/link to initiate the process is labeled "Disable Delete Protection" while the confirmation button is labeled "Disable API Delete Protection". The documentation should maintain these different labels to match the actual UI.

Applied to files:

  • apps/docs/errors/unkey/authorization/insufficient_permissions.mdx
  • apps/docs/apis/features/enabled.mdx
  • apps/docs/errors/unkey/application/protected_resource.mdx
  • apps/docs/errors/unkey/authorization/key_disabled.mdx
  • apps/docs/apis/features/authorization/verifying.mdx
  • apps/docs/security/recovering-keys.mdx
  • apps/docs/errors/unkey/authorization/workspace_disabled.mdx
  • apps/docs/apis/features/authorization/example.mdx
  • apps/docs/errors/unkey/application/service_unavailable.mdx
  • apps/docs/apis/features/authorization/roles-and-permissions.mdx
  • apps/docs/apis/features/ratelimiting/overview.mdx
  • apps/docs/docs.json
  • apps/docs/errors/unkey/data/api_not_found.mdx
📚 Learning: in the unkey codebase, input validation for api endpoints is handled at the openapi schema layer, wh...
Learnt from: chronark
PR: unkeyed/unkey#3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.

Applied to files:

  • apps/docs/errors/unkey/authorization/insufficient_permissions.mdx
  • apps/docs/apis/introduction.mdx
  • apps/docs/apis/features/authorization/verifying.mdx
  • apps/docs/migrations/introduction.mdx
  • apps/docs/errors/unkey/application/service_unavailable.mdx
  • apps/docs/apis/features/ratelimiting/overview.mdx
  • apps/docs/errors/unkey/data/permission_not_found.mdx
📚 Learning: in the unkey codebase, using non-standard http status code 529 for internal-only endpoints is accept...
Learnt from: Flo4604
PR: unkeyed/unkey#3647
File: go/apps/api/openapi/openapi-generated.yaml:3569-3575
Timestamp: 2025-07-22T18:09:41.800Z
Learning: In the Unkey codebase, using non-standard HTTP status code 529 for internal-only endpoints is acceptable and should not be flagged as an issue in future reviews.

Applied to files:

  • apps/docs/errors/unkey/application/unexpected_error.mdx
  • apps/docs/errors/unkey/application/protected_resource.mdx
  • apps/docs/errors/unkey/authorization/key_disabled.mdx
  • apps/docs/errors/unkey/application/service_unavailable.mdx
  • apps/docs/errors/unkey/data/key_not_found.mdx
📚 Learning: in the api key creation form, the json validation is properly handled by the validatejson function w...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3156
File: apps/dashboard/app/(app)/apis/[apiId]/_components/create-key/components/metadata-setup.tsx:97-104
Timestamp: 2025-04-28T12:23:48.891Z
Learning: In the API key creation form, the JSON validation is properly handled by the validateJSON function which uses try/catch, and is applied during form validation to prevent invalid JSON from being submitted.

Applied to files:

  • apps/docs/errors/unkey/application/unexpected_error.mdx
  • apps/docs/errors/unkey/data/api_not_found.mdx
📚 Learning: the v2 update identity endpoint (go/apps/api/routes/v2_identities_update_identity/handler.go) intent...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3661
File: go/apps/api/routes/v2_identities_update_identity/handler.go:115-119
Timestamp: 2025-07-28T11:47:43.144Z
Learning: The v2 update identity endpoint (go/apps/api/routes/v2_identities_update_identity/handler.go) intentionally uses `ExternalId` field instead of the unified `Identity` field used in other v2 identity endpoints. This is because the update endpoint needs to both find by externalId and potentially update the externalId value, making the specific field name more appropriate than the generic `Identity` field.

Applied to files:

  • apps/docs/errors/unkey/data/identity_already_exists.mdx
  • apps/docs/errors/unkey/data/identity_not_found.mdx
  • apps/docs/quickstart/identities/shared-ratelimits.mdx
  • apps/docs/apis/features/temp-keys.mdx
📚 Learning: ensure that audit log descriptions accurately reflect the action being performed, such as updating t...
Learnt from: chronark
PR: unkeyed/unkey#2146
File: apps/dashboard/lib/trpc/routers/api/setDefaultPrefix.ts:80-80
Timestamp: 2024-10-04T17:27:08.666Z
Learning: Ensure that audit log descriptions accurately reflect the action being performed, such as updating the `defaultPrefix`, and avoid incorrect references like 'name' when not applicable.

Applied to files:

  • apps/docs/errors/unkey/data/audit_log_not_found.mdx
📚 Learning: for destructive operations like deletion in the unkey api, oneof validation is preferred over anyof ...
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For destructive operations like deletion in the Unkey API, oneOf validation is preferred over anyOf to enforce explicit targeting and prevent ambiguity.

Applied to files:

  • apps/docs/errors/unkey/application/protected_resource.mdx
📚 Learning: in apps/dashboard/app/(app)/projects/[projectid]/diff/[...compare]/components/client.tsx, mcstepp pr...
Learnt from: mcstepp
PR: unkeyed/unkey#3662
File: apps/dashboard/app/(app)/projects/[projectId]/diff/[...compare]/components/client.tsx:322-341
Timestamp: 2025-07-28T20:38:53.244Z
Learning: In apps/dashboard/app/(app)/projects/[projectId]/diff/[...compare]/components/client.tsx, mcstepp prefers to keep hardcoded endpoint logic in the getDiffType function during POC phases for demonstrating diff functionality, rather than implementing a generic diff algorithm. This follows the pattern of keeping simplified implementations for demonstration purposes.

Applied to files:

  • apps/docs/libraries/ts/hono.mdx
  • apps/docs/libraries/ts/nextjs.mdx
📚 Learning: in apps/dashboard/lib/trpc/routers/deployment/getopenapidiff.ts, the user mcstepp prefers to keep mo...
Learnt from: mcstepp
PR: unkeyed/unkey#3662
File: apps/dashboard/lib/trpc/routers/deployment/getOpenApiDiff.ts:110-147
Timestamp: 2025-07-25T19:11:00.208Z
Learning: In apps/dashboard/lib/trpc/routers/deployment/getOpenApiDiff.ts, the user mcstepp prefers to keep mock data fallbacks in POC/demonstration code for simplicity, even if it wouldn't be production-ready. This aligns with the PR being work-in-progress for demonstration purposes.

Applied to files:

  • apps/docs/libraries/ts/hono.mdx
📚 Learning: in hono & cloudflare workers templates, the 'setup and installation' section in the readme serves as...
Learnt from: Devansh-Baghel
PR: unkeyed/unkey#2452
File: oss.gg/7_create_a_template.md:42-42
Timestamp: 2024-10-15T19:57:16.520Z
Learning: In Hono & Cloudflare Workers templates, the 'Setup and Installation' section in the README serves as the quickstart guide.

Applied to files:

  • apps/docs/libraries/ts/hono.mdx
📚 Learning: the unkey team uses linear for issue tracking rather than github issues....
Learnt from: MichaelUnkey
PR: unkeyed/unkey#3103
File: apps/dashboard/app/(app)/settings/general/page.tsx:36-36
Timestamp: 2025-04-14T13:39:22.635Z
Learning: The Unkey team uses Linear for issue tracking rather than GitHub Issues.

Applied to files:

  • apps/docs/analytics/overview.mdx
📚 Learning: in the unkey codebase, role and permission names are validated at the openapi schema layer with stri...
Learnt from: chronark
PR: unkeyed/unkey#3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.

Applied to files:

  • apps/docs/apis/features/authorization/verifying.mdx
  • apps/docs/apis/features/authorization/roles-and-permissions.mdx
  • apps/docs/errors/unkey/data/permission_not_found.mdx
  • apps/docs/errors/unkey/data/role_not_found.mdx
📚 Learning: there are two different `getauth` functions in the unkey codebase with different purposes: 1. `@/lib...
Learnt from: mcstepp
PR: unkeyed/unkey#3210
File: apps/dashboard/app/new/page.tsx:3-3
Timestamp: 2025-04-30T15:25:33.917Z
Learning: There are two different `getAuth` functions in the Unkey codebase with different purposes:
1. `@/lib/auth/get-auth` - Base function without redirects, used in special cases on the dashboard where redirect control is needed (like `/new` page) and within tRPC context
2. `@/lib/auth` - Helper function with redirects, used in most dashboard cases (approximately 98%)

Applied to files:

  • apps/docs/errors/unkey/authentication/missing.mdx
📚 Learning: in the unkey codebase, example values in documentation and demo components intentionally use themed ...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2910
File: apps/engineering/content/design/components/form/form-input.variants.tsx:38-38
Timestamp: 2025-02-24T13:35:00.816Z
Learning: In the Unkey codebase, example values in documentation and demo components intentionally use themed fake data (e.g., Middle Earth references) rather than generic placeholder text.

Applied to files:

  • apps/docs/errors/unkey/authentication/missing.mdx
  • apps/docs/errors/unkey/data/key_auth_not_found.mdx
📚 Learning: in next.js applications, importing backend modules into frontend components causes bundling issues a...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3311
File: apps/dashboard/components/logs/llm-search/components/search-input.tsx:14-14
Timestamp: 2025-06-10T14:21:42.413Z
Learning: In Next.js applications, importing backend modules into frontend components causes bundling issues and can expose server-side code to the client bundle. For simple constants like limits, it's acceptable to duplicate the value rather than compromise the frontend/backend architectural separation.

Applied to files:

  • apps/docs/libraries/ts/nextjs.mdx
📚 Learning: in the unkey dashboard, next.js router (router.push) should be used for client-side navigation inste...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3242
File: apps/dashboard/app/(app)/apis/[apiId]/_overview/components/table/components/override-indicator.tsx:50-65
Timestamp: 2025-05-15T16:26:08.666Z
Learning: In the Unkey dashboard, Next.js router (router.push) should be used for client-side navigation instead of window.location.href to preserve client state and enable smoother transitions between pages.

Applied to files:

  • apps/docs/libraries/ts/nextjs.mdx
📚 Learning: applies to **/*.{js,jsx,ts,tsx} : prefer named exports over default exports in typescript/javascript...
Learnt from: CR
PR: unkeyed/unkey#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-04T07:44:39.438Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Prefer named exports over default exports in TypeScript/JavaScript, except for Next.js pages

Applied to files:

  • apps/docs/libraries/ts/nextjs.mdx
📚 Learning: applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,...
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Update relevant anchors when modifying associated code.

Applied to files:

  • apps/docs/libraries/ts/nextjs.mdx
  • apps/docs/docs.json
📚 Learning: the `cloudflareratelimiter` type definition in `apps/api/src/pkg/env.ts` should not have its interfa...
Learnt from: chronark
PR: unkeyed/unkey#2544
File: apps/api/src/pkg/env.ts:4-6
Timestamp: 2024-10-23T12:05:31.121Z
Learning: The `cloudflareRatelimiter` type definition in `apps/api/src/pkg/env.ts` should not have its interface changed; it should keep the `limit` method returning `Promise<{ success: boolean }>` without additional error properties.

Applied to files:

  • apps/docs/apis/features/ratelimiting/overview.mdx
  • apps/docs/quickstart/identities/shared-ratelimits.mdx
📚 Learning: in `apps/api/src/pkg/keys/service.ts`, `ratelimitasync` is a table relation, not a column selection....
Learnt from: chronark
PR: unkeyed/unkey#2294
File: apps/api/src/pkg/keys/service.ts:268-271
Timestamp: 2024-10-20T07:05:55.471Z
Learning: In `apps/api/src/pkg/keys/service.ts`, `ratelimitAsync` is a table relation, not a column selection. When querying, ensure that table relations are included appropriately, not as columns.

Applied to files:

  • apps/docs/apis/features/ratelimiting/overview.mdx
  • apps/docs/quickstart/identities/shared-ratelimits.mdx
📚 Learning: in the rate limit test files (e.g., `apps/api/src/routes/v1_ratelimit_getoverride.happy.test.ts`), u...
Learnt from: chronark
PR: unkeyed/unkey#2126
File: apps/api/src/routes/v1_ratelimit_getOverride.happy.test.ts:36-36
Timestamp: 2024-11-13T19:06:36.786Z
Learning: In the rate limit test files (e.g., `apps/api/src/routes/v1_ratelimit_getOverride.happy.test.ts`), URL parameters like `namespaceId` and `identifier` do not need to be URL-encoded in the test code because the values used are always considered safe within the test environment.

Applied to files:

  • apps/docs/apis/features/ratelimiting/overview.mdx
  • apps/docs/quickstart/identities/shared-ratelimits.mdx
📚 Learning: in the unkey codebase, there is a mechanism to set the server's time via a header for test control, ...
Learnt from: chronark
PR: unkeyed/unkey#3474
File: go/apps/api/routes/v2_keys_verify_key/200_test.go:380-380
Timestamp: 2025-07-14T08:15:56.747Z
Learning: In the Unkey codebase, there is a mechanism to set the server's time via a header for test control, which helps make ratelimit tests deterministic instead of time-dependent. This is useful for preventing flaky tests where the second request might hit a new ratelimit window.

Applied to files:

  • apps/docs/apis/features/ratelimiting/overview.mdx
📚 Learning: in the unkey codebase, avoid hardcoding ids or indices that depend on array positions, as the arrays...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2876
File: apps/dashboard/components/logs/datetime/constants.ts:96-96
Timestamp: 2025-02-06T17:41:47.228Z
Learning: In the Unkey codebase, avoid hardcoding IDs or indices that depend on array positions, as the arrays may be modified in the future. Instead, use methods like `find` with unique identifiers or properties to locate specific items.

Applied to files:

  • apps/docs/errors/unkey/data/identity_not_found.mdx
  • apps/docs/errors/unkey/data/key_not_found.mdx
📚 Learning: in the create-key form's generalsetup component, the controller is intentionally bound to "identityi...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3315
File: apps/dashboard/app/(app)/apis/[apiId]/_components/create-key/components/general-setup.tsx:40-50
Timestamp: 2025-06-19T13:01:55.338Z
Learning: In the create-key form's GeneralSetup component, the Controller is intentionally bound to "identityId" as the primary field while "externalId" is set explicitly via setValue. The ExternalIdField component has been designed to handle this pattern where it receives identityId as its value prop but manages both identityId and externalId through its onChange callback.

Applied to files:

  • apps/docs/quickstart/identities/shared-ratelimits.mdx
📚 Learning: the `signinviaoauth` method in `baseauthprovider` is intentionally designed to be synchronous (retur...
Learnt from: mcstepp
PR: unkeyed/unkey#3215
File: apps/dashboard/lib/auth/base-provider.ts:112-118
Timestamp: 2025-05-05T17:57:38.099Z
Learning: The `signInViaOAuth` method in `BaseAuthProvider` is intentionally designed to be synchronous (returning `string` rather than `Promise<string>`) to match Unkey's authentication SDK implementation. Self-hosting users who implement their own auth providers can modify the base provider signature if needed.

Applied to files:

  • apps/docs/quickstart/identities/shared-ratelimits.mdx
📚 Learning: in `authorization/roles/[roleid]/update-role.tsx`, the tag `role-${role.id}` is revalidated after up...
Learnt from: AkshayBandi027
PR: unkeyed/unkey#2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In `authorization/roles/[roleId]/update-role.tsx`, the tag `role-${role.id}` is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.

Applied to files:

  • apps/docs/quickstart/identities/shared-ratelimits.mdx
  • apps/docs/errors/unkey/data/role_not_found.mdx
📚 Learning: the unkey dashboard's form validation for numeric values like rate limits is handled through the zod...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3156
File: apps/dashboard/app/(app)/apis/[apiId]/_components/create-key/components/ratelimit-setup.tsx:36-47
Timestamp: 2025-04-22T11:48:39.670Z
Learning: The Unkey dashboard's form validation for numeric values like rate limits is handled through the Zod schema validation (with `.positive()` validators and additional checks in `superRefine`), rather than HTML input attributes like `min`.

Applied to files:

  • apps/docs/quickstart/identities/shared-ratelimits.mdx
📚 Learning: in the authorization roles refactor, the rolebasic type uses `roleid` as the property name for the r...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3324
File: apps/dashboard/app/(app)/authorization/roles/components/table/components/actions/keys-table-action.popover.constants.tsx:17-18
Timestamp: 2025-06-19T11:48:05.070Z
Learning: In the authorization roles refactor, the RoleBasic type uses `roleId` as the property name for the role identifier, not `id`. This is consistent throughout the codebase in apps/dashboard/lib/trpc/routers/authorization/roles/query.ts.

Applied to files:

  • apps/docs/errors/unkey/data/role_not_found.mdx
🪛 Gitleaks (8.27.2)
apps/docs/errors/unkey/application/unexpected_error.mdx

38-40: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

apps/docs/errors/unkey/data/identity_already_exists.mdx

63-65: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

apps/docs/errors/unkey/data/audit_log_not_found.mdx

39-40: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)


58-59: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

apps/docs/errors/unkey/authentication/key_not_found.mdx

37-39: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)


58-60: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

apps/docs/errors/unkey/application/protected_resource.mdx

37-39: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

apps/docs/errors/unkey/authentication/malformed.mdx

37-39: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)


53-55: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

apps/docs/errors/unkey/application/service_unavailable.mdx

37-39: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

apps/docs/errors/unkey/data/identity_not_found.mdx

39-41: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)


58-59: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

apps/docs/errors/unkey/data/api_not_found.mdx

39-41: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)


60-61: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

apps/docs/errors/unkey/data/role_not_found.mdx

46-47: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

🪛 LanguageTool
apps/docs/libraries/ts/hono.mdx

[grammar] ~123-~123: Use correct spacing
Context: ...verify-api-key) for the full response object. ts app.use( "*", unkey({ rootKey: process.env.UNKEY_ROOT_KEY!, handleInvalidKey: (c, result) => { return c.json( { error: "unauthorized", reason: result.data.code, }, 401 ); }, }) ); ### Pass verification tags You can pass tag...

(QB_NEW_EN_OTHER_ERROR_IDS_5)

apps/docs/quickstart/identities/shared-ratelimits.mdx

[grammar] ~37-~37: Use correct spacing
Context: ... store additional information about the identity. Unkey does not care what the `externalId...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~39-~39: There might be a mistake here.
Context: ... Commonly used are user or organization ids. The meta object can be used to store ...

(QB_NEW_EN_OTHER)


[grammar] ~39-~39: Use correct spacing
Context: ...ormation you want to associate with the identity. ts const externalId = "user_1234abc"; const createIdentityResponse = await fetch("https://api.unkey.com/v2/identities.createIdentity", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${rootKey}`, }, body: JSON.stringify({ externalId, meta: { stripeCustomerId: "cus_123", }, }), }); const { identityId } = await createIdentityResponse.json<{ identityId: string; }>(); ### Retrieve an Identity Let's retrieve the...

(QB_NEW_EN_OTHER_ERROR_IDS_5)

apps/docs/apis/features/temp-keys.mdx

[grammar] ~11-~11: Use correct spacing
Context: ...the parameters you can send in the API Reference. bash curl --request POST \ --url https://api.unkey.com/v2/keys.createKey \ --header 'Authorization: Bearer <UNKEY>' \ --header 'Content-Type: application/json' \ --data '{ "apiId":"<API_ID>", "prefix":"xyz", "byteLength":16, "externalId":"USER_ID", "expires": 1718718673000 }' Once the key is created, you can send it...

(QB_NEW_EN_OTHER_ERROR_IDS_5)

🪛 GitHub Actions: autofix.ci
apps/docs/libraries/ts/hono.mdx

[error] 41-41: Syntax error: Unable to parse file due to unexpected character '"' in attribute name at line 41, column 99.

🔇 Additional comments (37)
apps/docs/docs.json (2)

219-219: 👍 Clear deprecation labelling

Renaming the dropdown to “api.unkey.dev/v1 (deprecated)” improves discoverability and nudges users towards v2. Looks good.


100-105: No broken navigation – ratelimiting/modes.mdx is present
I ran fd --full-path ratelimiting/modes.mdx and confirmed that apps/docs/ratelimiting/modes.mdx still exists, so the link in the top-level “Ratelimiting” group will resolve correctly. No changes needed.

apps/docs/migrations/keys.mdx (1)

5-7: LGTM – helpful clarification

The added makes it explicit that migration endpoints are still v1-only. No issues spotted.

apps/docs/migrations/introduction.mdx (1)

7-9: LGTM – consistent v1 notice

Matches the wording added to keys.mdx, keeping messaging consistent.

apps/docs/analytics/overview.mdx (1)

6-8: LGTM – v1 analytics disclaimer

Clear upfront notice; no further action needed.

apps/docs/errors/unkey/authentication/key_not_found.mdx (1)

37-40: Endpoint version bump is accurate – no further action required

keys.listKeys examples now correctly target https://api.unkey.com/v2. Payload/headers remain valid for v2, so nothing else to change here.

Also applies to: 58-61

apps/docs/api-reference/v2/auth.mdx (1)

20-24: Good catch updating the createKey example to v2

The switch to the production domain & v2 path is correct and consistent with the rest of the docs.

apps/docs/errors/unkey/authentication/missing.mdx (1)

31-33: Examples correctly migrated to v2

Both unauthenticated and corrected request examples now reference the v2 keys.listKeys endpoint – looks good.

Also applies to: 51-54

apps/docs/errors/unkey/data/identity_already_exists.mdx (1)

63-73: updateIdentity sample aligned with v2

Endpoint path and HTTP method match current API design; example body still conforms to the v2 contract.

apps/docs/errors/unkey/application/unexpected_error.mdx (1)

38-38: Endpoint version bump LGTM

Example updated from /v1/… to /v2/…; matches the ongoing migration. Nothing else to flag.

apps/docs/apis/features/refill.mdx (2)

20-30: URL migration looks correct

The create-key example now hits api.unkey.com/v2/keys.createKey. Header / payload remain valid for v2; no further changes required.


37-41: Verify-key example aligns with v2

keys.verifyKey no longer needs an Authorization header, so the omission is fine.

apps/docs/errors/unkey/authorization/workspace_disabled.mdx (1)

31-33: Endpoint version bump LGTM

Example now correctly references the v2 keys.listKeys endpoint.

apps/docs/errors/unkey/authorization/insufficient_permissions.mdx (1)

37-44: Both example curl commands updated – good, but watch for mixed environments

Endpoints are now on /v2/keys.createKey, matching the PR goal.
Double-check that other references in this file (and siblings) don’t still point at the old dev domain (api.unkey.dev) to keep examples consistent.

Also applies to: 57-64

apps/docs/errors/unkey/application/service_unavailable.mdx (1)

37-44: v2 migration looks correct

Both the single request example and the retry script now hit /v2/keys.createKey.
The token shown (unkey_YOUR_API_KEY) is obviously a placeholder, so the Gitleaks warning can be safely ignored.

Also applies to: 65-66

apps/docs/errors/unkey/data/key_auth_not_found.mdx (1)

47-53: Endpoint upgraded to v2 – verify other helper snippets

Good catch updating keys.getKey to /v2. If you removed other outdated examples in this doc (as suggested in the AI summary) make sure any cross-links still reference existing sections.

apps/docs/apis/introduction.mdx (1)

76-80: Endpoint sample no longer matches earlier TypeScript/Golang snippets

The cURL example now targets the v2 endpoint and omits the apiId field, but:

  • Lines 14-17 (TypeScript) still pass apiId
  • Lines 62-64 (Go) still use the v1-specific request model

Readers will be confused about which payload is correct. Align all language samples with the new v2 contract (no apiId) and update the Go model type.

apps/docs/errors/unkey/authorization/key_disabled.mdx (2)

31-34: LGTM – update looks correct

Endpoint version bump and placeholder token are accurate; content-type header is already present.


61-64: LGTM – duplicated example consistent

Same comment as above; no further action required.

apps/docs/apis/features/ratelimiting/overview.mdx (1)

20-34: Endpoints correctly migrated to v2

All ratelimit examples now reference the v2 domain; headers and payloads remain unchanged.
No issues spotted.

Also applies to: 38-44, 50-63, 67-79, 86-106, 122-148, 135-148, 157-170

apps/docs/apis/features/authorization/verifying.mdx (2)

16-25: Good addition of Authorization header

Including the bearer token makes the example immediately usable and consistent with other docs.


31-50: Second example updated consistently

Same positive feedback applies here.

apps/docs/errors/unkey/authentication/malformed.mdx (1)

37-37: Endpoint version bump looks correct

The sample requests now target /v2/keys.listKeys, which matches the ongoing doc migration to v2. No further issues spotted.

Also applies to: 53-53

apps/docs/apis/features/authorization/roles-and-permissions.mdx (1)

133-141: v2 endpoint confirmed – double-check payload fields

The URL switch to https://api.unkey.com/v2/keys.createKey is correct.
Please verify that the apiId field is still required in v2 and update docs accordingly if the server now infers it from the auth context.

apps/docs/apis/features/temp-keys.mdx (1)

11-11: Ensure parameter names align with v2 schema

You replaced ownerId with externalId and moved to the v2 keys.createKey RPC.
Confirm that:

  1. externalId is the canonical field in the v2 OpenAPI spec.
  2. No lingering docs still reference the old ownerId field.

If needed, I can grep the repo for outdated references.

Also applies to: 15-15, 22-23

apps/docs/errors/unkey/data/key_not_found.mdx (1)

39-41: URL migration LGTM

Both sample calls now hit the v2 endpoints; headers and payload snippets remain valid.

Also applies to: 59-59

apps/docs/errors/unkey/data/permission_not_found.mdx (1)

45-48: Inconsistent header usage for POST example

permissions.listPermissions is invoked via POST but the example omits a Content-Type: application/json header or body.
If the endpoint truly expects an empty body that’s fine, otherwise add the header + {} body for clarity & parity with other examples.

apps/docs/errors/unkey/data/api_not_found.mdx (2)

39-46: LGTM – v2 endpoint & method look correct

Endpoints, headers and payload align with current API conventions.


60-62: Ditto for list APIs – looks good

POST method & endpoint updated correctly.

apps/docs/security/recovering-keys.mdx (1)

82-91: Example is clear & accurate

v2 keys.getKey sample correctly shows JSON body with decrypt: true.

apps/docs/errors/unkey/data/role_not_found.mdx (2)

46-48: Check that permissions.listRoles is a valid v2 endpoint

v1 exposed roles.listRoles; in the Go v2 router the listing endpoint still sits under the roles namespace. Using permissions.listRoles may produce a 404 in examples.

If the spec indeed changed, ignore this – otherwise update the path:

-curl -X POST https://api.unkey.com/v2/permissions.listRoles \
+curl -X POST https://api.unkey.com/v2/roles.listRoles \

53-59: Verify permissions.createRole vs roles.createRole

Same namespace concern as above. Confirm the official OpenAPI description; if the endpoint is still under roles adjust the sample accordingly:

-curl -X POST https://api.unkey.com/v2/permissions.createRole \
+curl -X POST https://api.unkey.com/v2/roles.createRole \
apps/docs/apis/features/remaining.mdx (2)

38-44: verifyKey example dropped apiId; other docs still include it

In this file the verify request omits apiId, whereas apps/docs/quickstart/identities/shared-ratelimits.mdx still sends it.
Confirm which form is required by the v2 API and make the examples consistent across docs.


76-83: Minor style nit – avoid trailing comma in single-property object

-    "credits": {
-      "cost": 4
-    }
+    "credits": { "cost": 4 }

Keeps the snippet compact while conveying the same information.

Likely an incorrect or invalid review comment.

apps/docs/quickstart/identities/shared-ratelimits.mdx (3)

68-77: Confirm that identities.getIdentity requires POST + JSON body

v1 exposed a GET with query params. If v2 still accepts GET (as some internal handlers do), consider keeping the simpler curl.
Otherwise this example is fine – just ensure the OpenAPI spec matches.


118-127: apiId parameter consistency

Here verifyKey still sends apiId, whereas the “Remaining credits” doc removed it. Harmonise after verifying the actual requirement.


37-40: Typo – double space after period

identity.␣␣Unkey → single space.

Tiny copy-editing fix for readability.

⛔ Skipped due to learnings
Learnt from: mcstepp
PR: unkeyed/unkey#3242
File: apps/dashboard/app/(app)/apis/[apiId]/api-id-navbar.tsx:47-50
Timestamp: 2025-05-15T15:57:02.128Z
Learning: When reviewing code for Unkey, prefer using `Boolean()` over the double negation (`!!`) operator for boolean coercion, as their linter rules favor this pattern.
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3661
File: go/apps/api/routes/v2_identities_update_identity/handler.go:115-119
Timestamp: 2025-07-28T11:47:43.144Z
Learning: The v2 update identity endpoint (go/apps/api/routes/v2_identities_update_identity/handler.go) intentionally uses `ExternalId` field instead of the unified `Identity` field used in other v2 identity endpoints. This is because the update endpoint needs to both find by externalId and potentially update the externalId value, making the specific field name more appropriate than the generic `Identity` field.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3315
File: apps/dashboard/app/(app)/apis/[apiId]/_components/create-key/components/general-setup.tsx:40-50
Timestamp: 2025-06-19T13:01:55.338Z
Learning: In the create-key form's GeneralSetup component, the Controller is intentionally bound to "identityId" as the primary field while "externalId" is set explicitly via setValue. The ExternalIdField component has been designed to handle this pattern where it receives identityId as its value prop but manages both identityId and externalId through its onChange callback.
Learnt from: Flo4604
PR: unkeyed/unkey#2955
File: go/apps/api/routes/v2_identities_create_identity/handler.go:162-202
Timestamp: 2025-03-19T09:25:59.751Z
Learning: In the Unkey codebase, input validation for API endpoints is primarily handled through OpenAPI schema validation, which occurs before requests reach the handler code. For example, in the identities.createIdentity endpoint, minimum values for ratelimit duration and limit are defined in the OpenAPI schema rather than duplicating these checks in the handler.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 39c46b9 and f35696f.

📒 Files selected for processing (3)
  • apps/docs/apis/features/authorization/example.mdx (3 hunks)
  • apps/docs/errors/unkey/data/identity_not_found.mdx (1 hunks)
  • apps/docs/libraries/ts/hono.mdx (3 hunks)
🧰 Additional context used
🧠 Learnings (26)
📓 Common learnings
Learnt from: Flo4604
PR: unkeyed/unkey#3421
File: go/apps/api/openapi/openapi.yaml:196-200
Timestamp: 2025-07-03T05:58:10.699Z
Learning: In the Unkey codebase, OpenAPI 3.1 is used, which allows sibling keys (such as `description`) alongside `$ref` in schema objects. Do not flag this as an error in future reviews.
Learnt from: MichaelUnkey
PR: unkeyed/unkey#3173
File: apps/docs/security/delete-protection.mdx:32-36
Timestamp: 2025-04-22T17:33:28.162Z
Learning: In the Unkey dashboard UI for delete protection, the button/link to initiate the process is labeled "Disable Delete Protection" while the confirmation button is labeled "Disable API Delete Protection". The documentation should maintain these different labels to match the actual UI.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3321
File: apps/dashboard/lib/trpc/routers/authorization/roles/keys/schema-with-helpers.ts:5-8
Timestamp: 2025-06-18T12:28:10.449Z
Learning: In the unkey dashboard application, API validation for pagination limits is controlled at the UI level rather than requiring additional server-side validation, as the APIs are internal and protected by UI logic.
Learnt from: MichaelUnkey
PR: unkeyed/unkey#3173
File: apps/docs/security/delete-protection.mdx:21-24
Timestamp: 2025-04-22T17:34:04.438Z
Learning: In the Unkey dashboard UI for enabling delete protection, the button/link to initiate the process is labeled "Enable Delete Protection" while the confirmation button is labeled "Enable API Delete Protection". The documentation should maintain these different labels to match the actual UI.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3242
File: apps/dashboard/app/(app)/apis/[apiId]/_overview/components/table/components/override-indicator.tsx:50-65
Timestamp: 2025-05-15T16:26:08.666Z
Learning: In the Unkey dashboard, Next.js router (router.push) should be used for client-side navigation instead of window.location.href to preserve client state and enable smoother transitions between pages.
📚 Learning: for identity deletion operations in the unkey api, identityid takes precedence over externalid when ...
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.

Applied to files:

  • apps/docs/errors/unkey/data/identity_not_found.mdx
📚 Learning: in `apps/api/src/routes/v1_keys_updatekey.ts`, the code intentionally handles `externalid` and `owne...
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.

Applied to files:

  • apps/docs/errors/unkey/data/identity_not_found.mdx
  • apps/docs/libraries/ts/hono.mdx
  • apps/docs/apis/features/authorization/example.mdx
📚 Learning: in the unkey codebase, avoid hardcoding ids or indices that depend on array positions, as the arrays...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2876
File: apps/dashboard/components/logs/datetime/constants.ts:96-96
Timestamp: 2025-02-06T17:41:47.228Z
Learning: In the Unkey codebase, avoid hardcoding IDs or indices that depend on array positions, as the arrays may be modified in the future. Instead, use methods like `find` with unique identifiers or properties to locate specific items.

Applied to files:

  • apps/docs/errors/unkey/data/identity_not_found.mdx
📚 Learning: in the unkey codebase, openapi 3.1 is used, which allows sibling keys (such as `description`) alongs...
Learnt from: Flo4604
PR: unkeyed/unkey#3421
File: go/apps/api/openapi/openapi.yaml:196-200
Timestamp: 2025-07-03T05:58:10.699Z
Learning: In the Unkey codebase, OpenAPI 3.1 is used, which allows sibling keys (such as `description`) alongside `$ref` in schema objects. Do not flag this as an error in future reviews.

Applied to files:

  • apps/docs/errors/unkey/data/identity_not_found.mdx
  • apps/docs/libraries/ts/hono.mdx
  • apps/docs/apis/features/authorization/example.mdx
📚 Learning: in the unkey codebase, input validation for api endpoints is primarily handled through openapi schem...
Learnt from: Flo4604
PR: unkeyed/unkey#2955
File: go/apps/api/routes/v2_identities_create_identity/handler.go:162-202
Timestamp: 2025-03-19T09:25:59.751Z
Learning: In the Unkey codebase, input validation for API endpoints is primarily handled through OpenAPI schema validation, which occurs before requests reach the handler code. For example, in the identities.createIdentity endpoint, minimum values for ratelimit duration and limit are defined in the OpenAPI schema rather than duplicating these checks in the handler.

Applied to files:

  • apps/docs/errors/unkey/data/identity_not_found.mdx
📚 Learning: when implementing endpoints that require a key, avoid sending the key as part of the url. use post m...
Learnt from: chronark
PR: unkeyed/unkey#2159
File: apps/api/src/routes/v1_keys_getWhoAmI.ts:12-13
Timestamp: 2024-10-08T15:33:04.290Z
Learning: When implementing endpoints that require a key, avoid sending the key as part of the URL. Use POST methods with the key in the request body instead, as URLs get logged and could leak sensitive information.

Applied to files:

  • apps/docs/errors/unkey/data/identity_not_found.mdx
  • apps/docs/apis/features/authorization/example.mdx
📚 Learning: in the unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` di...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.

Applied to files:

  • apps/docs/errors/unkey/data/identity_not_found.mdx
📚 Learning: when querying or updating namespaces in the unkey dashboard, always scope the operations to the curr...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: When querying or updating namespaces in the Unkey dashboard, always scope the operations to the current workspace using `eq(table.workspaceId, ctx.workspace.id)` to prevent cross-workspace access.

Applied to files:

  • apps/docs/errors/unkey/data/identity_not_found.mdx
📚 Learning: in apps/dashboard/lib/trpc/routers/deployment/getopenapidiff.ts, the user mcstepp prefers to keep mo...
Learnt from: mcstepp
PR: unkeyed/unkey#3662
File: apps/dashboard/lib/trpc/routers/deployment/getOpenApiDiff.ts:110-147
Timestamp: 2025-07-25T19:11:00.208Z
Learning: In apps/dashboard/lib/trpc/routers/deployment/getOpenApiDiff.ts, the user mcstepp prefers to keep mock data fallbacks in POC/demonstration code for simplicity, even if it wouldn't be production-ready. This aligns with the PR being work-in-progress for demonstration purposes.

Applied to files:

  • apps/docs/libraries/ts/hono.mdx
📚 Learning: applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,...
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Make sure to add relevant anchor comments whenever a file or piece of code is too complex, very important, confusing, or could have a bug.

Applied to files:

  • apps/docs/libraries/ts/hono.mdx
📚 Learning: applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,...
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Use `AIDEV-NOTE:`, `AIDEV-TODO:`, `AIDEV-BUSINESS_RULE:`, or `AIDEV-QUESTION:` (all-caps prefix) as anchor comments aimed at AI and developers.

Applied to files:

  • apps/docs/libraries/ts/hono.mdx
  • apps/docs/apis/features/authorization/example.mdx
📚 Learning: the `target` prop on `inlinelink` components in the @unkey/ui package is a boolean prop, not a strin...
Learnt from: chronark
PR: unkeyed/unkey#3324
File: apps/dashboard/app/(app)/authorization/roles/components/upsert-role/components/warning-callout.tsx:22-27
Timestamp: 2025-07-03T11:57:15.263Z
Learning: The `target` prop on `InlineLink` components in the unkey/ui package is a boolean prop, not a string. When `target` is truthy, it automatically sets `target="_blank"` and `rel="noopener noreferrer"` on the underlying anchor element. Using just `target` (equivalent to `target={true}`) is the correct way to make the link open in a new tab.

Applied to files:

  • apps/docs/libraries/ts/hono.mdx
📚 Learning: in the unkey api openapi schema, the permissions query regex for the verifykey endpoint intentionall...
Learnt from: chronark
PR: unkeyed/unkey#3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via `\s`. Do not flag this as an error in future reviews.

Applied to files:

  • apps/docs/libraries/ts/hono.mdx
  • apps/docs/apis/features/authorization/example.mdx
📚 Learning: when reviewing code for unkey, prefer using `boolean()` over the double negation (`!!`) operator for...
Learnt from: mcstepp
PR: unkeyed/unkey#3242
File: apps/dashboard/app/(app)/apis/[apiId]/api-id-navbar.tsx:47-50
Timestamp: 2025-05-15T15:57:02.128Z
Learning: When reviewing code for Unkey, prefer using `Boolean()` over the double negation (`!!`) operator for boolean coercion, as their linter rules favor this pattern.

Applied to files:

  • apps/docs/libraries/ts/hono.mdx
📚 Learning: in the unkey codebase, typescript and the env() function implementation already provide sufficient v...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3292
File: apps/dashboard/lib/trpc/routers/key/create.ts:11-14
Timestamp: 2025-06-02T11:09:58.791Z
Learning: In the unkey codebase, TypeScript and the env() function implementation already provide sufficient validation for environment variables, so additional runtime error handling for missing env vars is not needed.

Applied to files:

  • apps/docs/libraries/ts/hono.mdx
📚 Learning: in the rate limit test files (e.g., `apps/api/src/routes/v1_ratelimit_getoverride.happy.test.ts`), u...
Learnt from: chronark
PR: unkeyed/unkey#2126
File: apps/api/src/routes/v1_ratelimit_getOverride.happy.test.ts:36-36
Timestamp: 2024-11-13T19:06:36.786Z
Learning: In the rate limit test files (e.g., `apps/api/src/routes/v1_ratelimit_getOverride.happy.test.ts`), URL parameters like `namespaceId` and `identifier` do not need to be URL-encoded in the test code because the values used are always considered safe within the test environment.

Applied to files:

  • apps/docs/libraries/ts/hono.mdx
📚 Learning: in apps/dashboard/app/(app)/projects/page.tsx, the user mcstepp prefers to keep placeholder function...
Learnt from: mcstepp
PR: unkeyed/unkey#3662
File: apps/dashboard/app/(app)/projects/page.tsx:74-81
Timestamp: 2025-07-28T19:42:37.047Z
Learning: In apps/dashboard/app/(app)/projects/page.tsx, the user mcstepp prefers to keep placeholder functions like generateSlug inline during POC/demonstration phases rather than extracting them to utility modules, with plans to refactor later when the feature matures beyond the proof-of-concept stage.

Applied to files:

  • apps/docs/libraries/ts/hono.mdx
📚 Learning: in the unkey dashboard ui for enabling delete protection, the button/link to initiate the process is...
Learnt from: MichaelUnkey
PR: unkeyed/unkey#3173
File: apps/docs/security/delete-protection.mdx:21-24
Timestamp: 2025-04-22T17:34:04.438Z
Learning: In the Unkey dashboard UI for enabling delete protection, the button/link to initiate the process is labeled "Enable Delete Protection" while the confirmation button is labeled "Enable API Delete Protection". The documentation should maintain these different labels to match the actual UI.

Applied to files:

  • apps/docs/apis/features/authorization/example.mdx
📚 Learning: in the unkey dashboard ui for delete protection, the button/link to initiate the process is labeled ...
Learnt from: MichaelUnkey
PR: unkeyed/unkey#3173
File: apps/docs/security/delete-protection.mdx:32-36
Timestamp: 2025-04-22T17:33:28.162Z
Learning: In the Unkey dashboard UI for delete protection, the button/link to initiate the process is labeled "Disable Delete Protection" while the confirmation button is labeled "Disable API Delete Protection". The documentation should maintain these different labels to match the actual UI.

Applied to files:

  • apps/docs/apis/features/authorization/example.mdx
📚 Learning: in the authorization roles refactor, the rolebasic type uses `roleid` as the property name for the r...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3324
File: apps/dashboard/app/(app)/authorization/roles/components/table/components/actions/keys-table-action.popover.constants.tsx:17-18
Timestamp: 2025-06-19T11:48:05.070Z
Learning: In the authorization roles refactor, the RoleBasic type uses `roleId` as the property name for the role identifier, not `id`. This is consistent throughout the codebase in apps/dashboard/lib/trpc/routers/authorization/roles/query.ts.

Applied to files:

  • apps/docs/apis/features/authorization/example.mdx
📚 Learning: in `authorization/roles/[roleid]/update-role.tsx`, the tag `role-${role.id}` is revalidated after up...
Learnt from: AkshayBandi027
PR: unkeyed/unkey#2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In `authorization/roles/[roleId]/update-role.tsx`, the tag `role-${role.id}` is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.

Applied to files:

  • apps/docs/apis/features/authorization/example.mdx
📚 Learning: in the unkey codebase, role and permission names are validated at the openapi schema layer with stri...
Learnt from: chronark
PR: unkeyed/unkey#3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.

Applied to files:

  • apps/docs/apis/features/authorization/example.mdx
📚 Learning: the vault.ts file in apps/dashboard/lib/vault.ts is a duplicate of the vault package from the `api` ...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3292
File: apps/dashboard/lib/vault.ts:80-97
Timestamp: 2025-06-02T11:08:56.397Z
Learning: The vault.ts file in apps/dashboard/lib/vault.ts is a duplicate of the vault package from the `api` directory and should be kept consistent with that original implementation.

Applied to files:

  • apps/docs/apis/features/authorization/example.mdx
📚 Learning: in the unkey dashboard application, api validation for pagination limits is controlled at the ui lev...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3321
File: apps/dashboard/lib/trpc/routers/authorization/roles/keys/schema-with-helpers.ts:5-8
Timestamp: 2025-06-18T12:28:10.449Z
Learning: In the unkey dashboard application, API validation for pagination limits is controlled at the UI level rather than requiring additional server-side validation, as the APIs are internal and protected by UI logic.

Applied to files:

  • apps/docs/apis/features/authorization/example.mdx
📚 Learning: in the api key creation form, the json validation is properly handled by the validatejson function w...
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3156
File: apps/dashboard/app/(app)/apis/[apiId]/_components/create-key/components/metadata-setup.tsx:97-104
Timestamp: 2025-04-28T12:23:48.891Z
Learning: In the API key creation form, the JSON validation is properly handled by the validateJSON function which uses try/catch, and is applied during form validation to prevent invalid JSON from being submitted.

Applied to files:

  • apps/docs/apis/features/authorization/example.mdx
🪛 Gitleaks (8.27.2)
apps/docs/errors/unkey/data/identity_not_found.mdx

39-41: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

🪛 LanguageTool
apps/docs/apis/features/authorization/example.mdx

[grammar] ~79-~79: Ensure spelling is correct
Context: ...ar, click on one of your APIs 2. In the breakcrumb navigation on the top click Reqests and...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~79-~79: Add a comma
Context: ... 2. In the breakcrumb navigation on the top click Reqests and then keys ...

(QB_NEW_EN_OTHER_ERROR_IDS_22)


[grammar] ~79-~79: Ensure spelling is correct
Context: ... breakcrumb navigation on the top click Reqests and then keys <img sr...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~79-~79: There might be a mistake here.
Context: ...ation on the top click Reqests and then keys Breadcrumb Navigation 3. Select one of your existing keys by clic...

(QB_NEW_EN_OTHER)


[grammar] ~84-~84: There might be a mistake here.
Context: ...ne of your existing keys by clicking on it 4. Scroll down to the Roles section if no...

(QB_NEW_EN_OTHER)


[grammar] ~85-~85: There might be a mistake here.
Context: ...roll down to the Roles section if not visible You should now be on `/app/keys/key_auth...

(QB_NEW_EN_OTHER)


[grammar] ~126-~126: Use correct spacing
Context: ...i-reference/v2/keys/create-api-key) for details. Now you can verify this key and perform ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test Packages / Test
🔇 Additional comments (4)
apps/docs/errors/unkey/data/identity_not_found.mdx (1)

39-45: Endpoint correctly migrated to v2 with POST method – looks good

The example now matches current API conventions (production domain, /v2/ prefix, POST, proper headers). No further changes required.

apps/docs/apis/features/authorization/example.mdx (1)

126-126: Double-check updated reference link

Please verify that /api-reference/v2/keys/create-api-key is the final slug in the docs build. Some sections still use /api-reference/v2/keys/create, so ensure the link won’t 404.

apps/docs/libraries/ts/hono.mdx (2)

10-14: Quote fix and repo link update look good
The previously-broken href is now properly closed and the repo path points to the new sdks location.


132-135: Nested result.data.code change aligns with v2 payload
The example now matches the new response structure—no further action needed.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@graphite-app
Copy link

graphite-app bot commented Aug 7, 2025

Movie gif. Actor Chow Yun-fat leans out of a doorway casually chewing while giving a cool, confident thumbs-up of approval. (Added via Giphy)

@graphite-app
Copy link

graphite-app bot commented Aug 7, 2025

Graphite Automations

"Post a GIF when PR approved" took an action on this PR • (08/07/25)

1 gif was posted to this PR based on Andreas Thomas's automation.

@chronark chronark disabled auto-merge August 8, 2025 10:33
@chronark chronark merged commit 8c0c0b8 into main Aug 8, 2025
18 checks passed
@chronark chronark deleted the docs-v2 branch August 8, 2025 10:33
This was referenced Nov 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants