com um clique
api-testing
// Test the local Rudel API with authenticated requests. Use when the user wants to test API endpoints, debug RPC calls, verify auth flows, or inspect API responses against the local dev server.
// Test the local Rudel API with authenticated requests. Use when the user wants to test API endpoints, debug RPC calls, verify auth flows, or inspect API responses against the local dev server.
CRITICAL - Invoke BEFORE writing ANY test code. Use when creating new tests, adding test cases, modifying existing tests, writing `it()` or `describe()` blocks, or touching any `*.test.ts` or `*.spec.ts` file. Enforces no try-catch in positive tests, no early returns, no test skipping.
Environment variable management patterns. CRITICAL use when adding new environment variables (secrets, API keys, config), debugging "X not defined" or missing env var errors, tests passing locally but failing in CI, Turborepo not passing env vars to tasks, or troubleshooting deployment configuration errors.
Use when creating a pull request. Runs verification, reviews changes, and creates the PR with correct metadata. Invoke BEFORE pushing code.
TypeScript coding standards. Use when writing TypeScript, reviewing code, or refactoring. Enforces named exports, no dynamic imports, discriminated unions, proper type safety.
Query ClickHouse databases using the chcli CLI tool. Use when the user wants to run SQL queries against ClickHouse, explore database schemas, inspect tables, or extract data from ClickHouse.
Code architecture patterns. Use when organizing code, refactoring classes, designing service structure, or extracting/moving code to new files. Enforces function ordering, service functions over classes, dependency injection.
| name | api-testing |
| description | Test the local Rudel API with authenticated requests. Use when the user wants to test API endpoints, debug RPC calls, verify auth flows, or inspect API responses against the local dev server. |
| metadata | {"author":"rudel","version":"1.1"} |
| compatibility | Requires curl, jq, and a running local API server (bun run dev:local or bun run --cwd apps/api dev:env). |
| allowed-tools | Bash(curl:*) Bash(source:*) Bash(mkdir:*) Read |
Test authenticated requests against the local Rudel API (http://localhost:4010).
.env file at the project root with test credentials:API_TESTING_USER=user@example.com
API_TESTING_PASSWORD=yourpassword
API_TESTING_ORG=<organization-id>
The user must already exist in the database (created via the web UI or sign-up endpoint).
The API uses better-auth with cookie-based sessions. Sign in once, save the cookie, and reuse it for all subsequent requests.
mkdir -p .context && source .env && curl -s -c .context/cookies.txt \
-X POST http://localhost:4010/api/auth/sign-in/email \
-H "Content-Type: application/json" \
-d "{\"email\": \"$API_TESTING_USER\", \"password\": \"$API_TESTING_PASSWORD\"}"
This saves the better-auth.session_token cookie to .context/cookies.txt (gitignored).
The set-active endpoint requires an Origin header.
source .env && curl -s -b .context/cookies.txt -c .context/cookies.txt \
-X POST http://localhost:4010/api/auth/organization/set-active \
-H "Content-Type: application/json" \
-H "Origin: http://localhost:4010" \
-d "{\"organizationId\": \"$API_TESTING_ORG\"}"
This sets the org context for all subsequent analytics calls. Use both -b and -c since this updates the session cookie.
curl -s -b .context/cookies.txt \
-X POST http://localhost:4010/rpc/me \
-H "Content-Type: application/json" \
-d "{}" | jq
Expected: JSON with id, email, name, activeOrganizationId matching your API_TESTING_ORG.
All endpoint contracts and Zod schemas live in packages/api-routes/src/:
packages/api-routes/src/index.ts — The full RPC contract. Defines every endpoint with its input/output schemas. Read this to see all available methods and their exact types.packages/api-routes/src/schemas/analytics.ts — All analytics input/output Zod schemas (DaysInputSchema, OverviewKPIsSchema, SessionListInputSchema, etc.). Read this to see exact field names, types, and defaults for any analytics endpoint.packages/api-routes/src/schemas/source.ts — Ingest-related schemas (IngestSessionInput, etc.).To find the exact payload for any endpoint, read the contract in index.ts to find which schema it uses, then read that schema definition in schemas/.
The API uses oRPC. All RPC endpoints use POST /rpc/<method> with JSON body.
Important: Endpoints that take input require the body wrapped in {"json": {...}}. Endpoints without input accept {}.
# No input (e.g., me, listMyOrganizations)
curl -s -b .context/cookies.txt \
-X POST http://localhost:4010/rpc/<method> \
-H "Content-Type: application/json" \
-d '{}' | jq
# With input — wrap in {"json": {...}}
curl -s -b .context/cookies.txt \
-X POST http://localhost:4010/rpc/<method> \
-H "Content-Type: application/json" \
-d '{"json": {"days": 30}}' | jq
Responses are also wrapped: {"json": {...}}. Extract data with jq '.json'.
Auth-only endpoints (require session, no org context):
| Method | Input | Description |
|---|---|---|
me | {} | Get current user info |
listMyOrganizations | {} | List user's organizations |
ingestSession | {"json": IngestSessionInput} | Upload a session transcript |
getOrganizationSessionCount | {"json": {"organizationId": "..."}} | Count sessions for an org |
deleteOrganization | {"json": {"organizationId": "..."}} | Delete an org |
Org-scoped analytics endpoints (require session + active organization):
| Method | Input | Description |
|---|---|---|
analytics/overview/kpis | {"json": {"days": N}} | Overview KPIs |
analytics/overview/usageTrend | {"json": {"days": N}} | Usage trend data |
analytics/overview/modelTokensTrend | {"json": {"days": N}} | Model token trends |
analytics/overview/insights | {"json": {"days": N}} | Insights |
analytics/overview/teamSummaryComparison | {"json": {"days": N}} | Team summary comparison |
analytics/overview/successRate | {"json": {"days": N}} | Success rate |
analytics/developers/list | {"json": {"days": N}} | List developers |
analytics/developers/trends | {"json": {"days": N}} | Developer trends |
analytics/projects/investment | {"json": {"days": N}} | Project investment |
analytics/projects/trends | {"json": {"days": N}} | Project trends |
analytics/sessions/summary | {"json": {"days": N}} | Session summary |
analytics/roi/metrics | {"json": {"days": N}} | ROI metrics |
analytics/roi/trends | {"json": {"days": N}} | ROI trends |
analytics/users/mappings | {"json": {"days": N}} | User mappings |
# List organizations (no input)
curl -s -b .context/cookies.txt \
-X POST http://localhost:4010/rpc/listMyOrganizations \
-H "Content-Type: application/json" \
-d '{}' | jq '.json'
# Get overview KPIs for last 30 days (input wrapped in json)
curl -s -b .context/cookies.txt \
-X POST http://localhost:4010/rpc/analytics/overview/kpis \
-H "Content-Type: application/json" \
-d '{"json": {"days": 30}}' | jq '.json'
# Get usage trend for last 7 days
curl -s -b .context/cookies.txt \
-X POST http://localhost:4010/rpc/analytics/overview/usageTrend \
-H "Content-Type: application/json" \
-d '{"json": {"days": 7}}' | jq '.json'
# Get session count for an org
source .env && curl -s -b .context/cookies.txt \
-X POST http://localhost:4010/rpc/getOrganizationSessionCount \
-H "Content-Type: application/json" \
-d "{\"json\": {\"organizationId\": \"$API_TESTING_ORG\"}}" | jq '.json'
To switch to a different org than API_TESTING_ORG mid-session:
curl -s -b .context/cookies.txt -c .context/cookies.txt \
-X POST http://localhost:4010/api/auth/organization/set-active \
-H "Content-Type: application/json" \
-H "Origin: http://localhost:4010" \
-d '{"organizationId": "<other-org-id>"}'
Instead of cookies, you can extract a bearer token and use Authorization headers (this is what the CLI does):
# Extract token from session
TOKEN=$(curl -s -b .context/cookies.txt http://localhost:4010/api/cli-token | jq -r '.token')
# Use bearer token
curl -s -X POST http://localhost:4010/rpc/me \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d "{}" | jq '.json'
When RUDEL_LOG_DIR is set (configured in the prd_local Doppler env), the API writes logs to a daily file in that directory, resolved from the project root. The current value is .context, so logs are at:
.context/api-logs-YYYY-MM-DD.txt
For today's date, read .context/api-logs-$(date +%Y-%m-%d).txt. The log file contains all API debug-level output (requests, errors, ClickHouse queries, etc.).
When debugging errors: After a failing request, read the tail of the log file to see the server-side error, stack trace, or query details. This is especially useful for 500 errors where the curl response is generic.
{"json": {...}}. Endpoints with parameters require this wrapper.-H "Origin: http://localhost:4010" to better-auth API calls (/api/auth/*).bun run dev:local or bun run --cwd apps/api dev:env..context/api-logs-$(date +%Y-%m-%d).txt for the server-side stack trace..context/cookies.txt exists and is recent; if not, re-authenticate.jq '.json' to unwrap oRPC responses.-s (silent) with curl to suppress progress bars.me first after sign-in to verify the session is valid and see the user's activeOrganizationId.source .env to load them into the shell environment.