+ );
+}
+
function ClaudeUpstreamForm({
teamId,
kind,
@@ -759,6 +846,10 @@ function addKindLabel(kind: AddKind, t: Translator): string {
return t("kindCodex");
case "opencode":
return t("kindOpencode");
+ case "openai-apikey":
+ return t("kindOpenAiApiKey");
+ case "openrouter-apikey":
+ return t("kindOpenRouterApiKey");
default:
return claudeKindLabel(kind, t);
}
@@ -771,6 +862,10 @@ function nativeKindLabel(kind: CodeRouterAccountSummary["provider"], t: Translat
return t("kindCodex");
case "opencode-go":
return t("kindOpencodeGo");
+ case "openai-apikey":
+ return t("kindOpenAiApiKey");
+ case "openrouter-apikey":
+ return t("kindOpenRouterApiKey");
}
}
diff --git a/web/db/migrations/20260907150000_coderouter_api_key_providers/migration.sql b/web/db/migrations/20260907150000_coderouter_api_key_providers/migration.sql
new file mode 100644
index 000000000000..c636b996c996
--- /dev/null
+++ b/web/db/migrations/20260907150000_coderouter_api_key_providers/migration.sql
@@ -0,0 +1,20 @@
+-- coderouter routes the OpenAI Responses surface through pasted OpenAI and
+-- OpenRouter API keys as well as Codex sign-ins. The provider check on every
+-- coderouter table widens to admit the two key-based providers.
+ALTER TABLE "coderouter_accounts"
+ DROP CONSTRAINT IF EXISTS "coderouter_accounts_provider_check";
+ALTER TABLE "coderouter_accounts"
+ ADD CONSTRAINT "coderouter_accounts_provider_check"
+ CHECK ("provider" IN ('codex', 'opencode-go', 'openai-apikey', 'openrouter-apikey'));
+
+ALTER TABLE "coderouter_credentials"
+ DROP CONSTRAINT IF EXISTS "coderouter_credentials_provider_check";
+ALTER TABLE "coderouter_credentials"
+ ADD CONSTRAINT "coderouter_credentials_provider_check"
+ CHECK ("provider" IN ('codex', 'opencode-go', 'openai-apikey', 'openrouter-apikey'));
+
+ALTER TABLE "coderouter_session_accounts"
+ DROP CONSTRAINT IF EXISTS "coderouter_session_accounts_provider_check";
+ALTER TABLE "coderouter_session_accounts"
+ ADD CONSTRAINT "coderouter_session_accounts_provider_check"
+ CHECK ("provider" IN ('codex', 'opencode-go', 'openai-apikey', 'openrouter-apikey'));
diff --git a/web/db/schema.ts b/web/db/schema.ts
index 63b1e7dcacaa..41a7f7fb2815 100644
--- a/web/db/schema.ts
+++ b/web/db/schema.ts
@@ -1085,12 +1085,14 @@ export const subrouterTenants = pgTable(
* live in the envelope-encrypted coderouterCredentials table; this table
* coordinates selection and rotating refresh-token leases.
*/
+type CodeRouterProviderColumn = "codex" | "opencode-go" | "openai-apikey" | "openrouter-apikey";
+
export const coderouterAccounts = pgTable(
"coderouter_accounts",
{
id: uuid("id").defaultRandom().primaryKey(),
teamId: text("team_id").notNull(),
- provider: text("provider").$type<"codex" | "opencode-go">().notNull(),
+ provider: text("provider").$type