{ "openapi": "3.1.0", "info": { "title": "Latitude API", "version": "1.0.0", "description": "The Latitude public API. Authenticate using an API key via the `Authorization: Bearer` header." }, "servers": [ { "url": "https://api.latitude.so", "description": "Production" } ], "components": { "securitySchemes": { "ApiKeyAuth": { "type": "http", "scheme": "bearer", "description": "Organization-scoped API key" } }, "schemas": { "HealthResponse": { "type": "object", "properties": { "service": { "type": "string", "enum": [ "api" ] }, "status": { "type": "string", "enum": [ "ok" ] } }, "required": [ "service", "status" ] }, "OAuthProtectedResourceMetadata": { "type": "object", "properties": { "resource": { "type": "string" }, "authorization_servers": { "type": "array", "items": { "type": "string" } } }, "required": [ "resource", "authorization_servers" ] }, "Project": { "type": "object", "properties": { "id": { "type": "string" }, "organizationId": { "type": "string" }, "name": { "type": "string" }, "slug": { "type": "string" }, "deletedAt": { "type": [ "string", "null" ] }, "createdAt": { "type": "string" }, "updatedAt": { "type": "string" } }, "required": [ "id", "organizationId", "name", "slug", "deletedAt", "createdAt", "updatedAt" ] }, "Error": { "type": "object", "properties": { "error": { "type": "string" } }, "required": [ "error" ] }, "CreateProjectBody": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "description": "Project name" } }, "required": [ "name" ] }, "ProjectList": { "type": "object", "properties": { "projects": { "type": "array", "items": { "$ref": "#/components/schemas/Project" } } }, "required": [ "projects" ] }, "UpdateProjectBody": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "description": "New project name" } } }, "ScoreResponse": { "anyOf": [ { "$ref": "#/components/schemas/CustomScoreResponse" }, { "$ref": "#/components/schemas/EvaluationScoreResponse" } ] }, "CustomScoreResponse": { "type": "object", "properties": { "id": { "type": "string", "minLength": 24, "maxLength": 24 }, "organizationId": { "type": "string", "minLength": 24, "maxLength": 24 }, "projectId": { "type": "string", "minLength": 24, "maxLength": 24 }, "sessionId": { "type": [ "string", "null" ], "maxLength": 128 }, "traceId": { "type": [ "string", "null" ], "minLength": 32, "maxLength": 32 }, "spanId": { "type": [ "string", "null" ], "minLength": 16, "maxLength": 16 }, "simulationId": { "type": [ "string", "null" ], "minLength": 24, "maxLength": 24 }, "issueId": { "type": [ "string", "null" ], "minLength": 24, "maxLength": 24 }, "value": { "type": "number", "minimum": 0, "maximum": 1 }, "passed": { "type": "boolean" }, "feedback": { "type": "string" }, "error": { "type": [ "string", "null" ], "minLength": 1 }, "errored": { "type": "boolean" }, "duration": { "type": "integer", "minimum": 0 }, "tokens": { "type": "integer", "minimum": 0 }, "cost": { "type": "integer", "minimum": 0 }, "draftedAt": { "type": [ "string", "null" ], "format": "date-time" }, "annotatorId": { "type": [ "string", "null" ], "minLength": 24, "maxLength": 24 }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" }, "source": { "type": "string", "enum": [ "custom" ] }, "sourceId": { "type": "string", "minLength": 1, "maxLength": 128 }, "metadata": { "type": "object", "additionalProperties": {} } }, "required": [ "id", "organizationId", "projectId", "sessionId", "traceId", "spanId", "simulationId", "issueId", "value", "passed", "feedback", "error", "errored", "duration", "tokens", "cost", "draftedAt", "annotatorId", "createdAt", "updatedAt", "source", "sourceId", "metadata" ] }, "EvaluationScoreResponse": { "type": "object", "properties": { "id": { "type": "string", "minLength": 24, "maxLength": 24 }, "organizationId": { "type": "string", "minLength": 24, "maxLength": 24 }, "projectId": { "type": "string", "minLength": 24, "maxLength": 24 }, "sessionId": { "type": [ "string", "null" ], "maxLength": 128 }, "traceId": { "type": [ "string", "null" ], "minLength": 32, "maxLength": 32 }, "spanId": { "type": [ "string", "null" ], "minLength": 16, "maxLength": 16 }, "simulationId": { "type": [ "string", "null" ], "minLength": 24, "maxLength": 24 }, "issueId": { "type": [ "string", "null" ], "minLength": 24, "maxLength": 24 }, "value": { "type": "number", "minimum": 0, "maximum": 1 }, "passed": { "type": "boolean" }, "feedback": { "type": "string" }, "error": { "type": [ "string", "null" ], "minLength": 1 }, "errored": { "type": "boolean" }, "duration": { "type": "integer", "minimum": 0 }, "tokens": { "type": "integer", "minimum": 0 }, "cost": { "type": "integer", "minimum": 0 }, "draftedAt": { "type": [ "string", "null" ], "format": "date-time" }, "annotatorId": { "type": [ "string", "null" ], "minLength": 24, "maxLength": 24 }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" }, "source": { "type": "string", "enum": [ "evaluation" ] }, "sourceId": { "type": "string", "minLength": 24, "maxLength": 24 }, "metadata": { "type": "object", "properties": { "evaluationHash": { "type": "string" } }, "required": [ "evaluationHash" ] } }, "required": [ "id", "organizationId", "projectId", "sessionId", "traceId", "spanId", "simulationId", "issueId", "value", "passed", "feedback", "error", "errored", "duration", "tokens", "cost", "draftedAt", "annotatorId", "createdAt", "updatedAt", "source", "sourceId", "metadata" ] }, "CreateScoreBody": { "anyOf": [ { "$ref": "#/components/schemas/CreateCustomScoreBody" }, { "$ref": "#/components/schemas/CreateEvaluationScoreBody" } ] }, "CreateCustomScoreBody": { "type": "object", "properties": { "simulationId": { "type": [ "string", "null" ], "minLength": 24, "maxLength": 24, "default": null }, "value": { "type": "number", "minimum": 0, "maximum": 1 }, "passed": { "type": "boolean" }, "feedback": { "type": "string" }, "error": { "type": [ "string", "null" ], "minLength": 1, "default": null }, "duration": { "type": "integer", "minimum": 0, "default": 0 }, "tokens": { "type": "integer", "minimum": 0, "default": 0 }, "cost": { "type": "integer", "minimum": 0, "default": 0 }, "trace": { "$ref": "#/components/schemas/TraceRef" }, "sourceId": { "type": "string", "minLength": 1, "maxLength": 128 }, "metadata": { "type": "object", "additionalProperties": {}, "default": {} }, "_evaluation": { "type": "boolean", "enum": [ false ], "default": false } }, "required": [ "value", "passed", "feedback", "trace", "sourceId" ] }, "TraceRef": { "oneOf": [ { "type": "object", "properties": { "by": { "type": "string", "enum": [ "id" ] }, "id": { "type": "string", "minLength": 32, "maxLength": 32 } }, "required": [ "by", "id" ] }, { "type": "object", "properties": { "by": { "type": "string", "enum": [ "filters" ] }, "filters": { "$ref": "#/components/schemas/FilterSet" } }, "required": [ "by", "filters" ] } ] }, "FilterSet": { "type": "object", "additionalProperties": { "type": "array", "items": { "$ref": "#/components/schemas/FilterCondition" } } }, "FilterCondition": { "type": "object", "properties": { "op": { "type": "string", "enum": [ "eq", "neq", "gt", "gte", "lt", "lte", "in", "notIn", "contains", "notContains", "gtePercentile" ] }, "value": { "anyOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "array", "items": { "anyOf": [ { "type": "string" }, { "type": "number" } ] } } ] } }, "required": [ "op", "value" ] }, "CreateEvaluationScoreBody": { "type": "object", "properties": { "simulationId": { "type": [ "string", "null" ], "minLength": 24, "maxLength": 24, "default": null }, "value": { "type": "number", "minimum": 0, "maximum": 1 }, "passed": { "type": "boolean" }, "feedback": { "type": "string" }, "error": { "type": [ "string", "null" ], "minLength": 1, "default": null }, "duration": { "type": "integer", "minimum": 0, "default": 0 }, "tokens": { "type": "integer", "minimum": 0, "default": 0 }, "cost": { "type": "integer", "minimum": 0, "default": 0 }, "trace": { "$ref": "#/components/schemas/TraceRef" }, "_evaluation": { "type": "boolean", "enum": [ true ] }, "sourceId": { "type": "string", "minLength": 24, "maxLength": 24 }, "metadata": { "type": "object", "properties": { "evaluationHash": { "type": "string" } }, "required": [ "evaluationHash" ] } }, "required": [ "value", "passed", "feedback", "trace", "_evaluation", "sourceId", "metadata" ], "description": "Internal, don't use" }, "AnnotationScoreResponse": { "type": "object", "properties": { "id": { "type": "string", "minLength": 24, "maxLength": 24 }, "organizationId": { "type": "string", "minLength": 24, "maxLength": 24 }, "projectId": { "type": "string", "minLength": 24, "maxLength": 24 }, "sessionId": { "type": [ "string", "null" ], "maxLength": 128 }, "traceId": { "type": [ "string", "null" ], "minLength": 32, "maxLength": 32 }, "spanId": { "type": [ "string", "null" ], "minLength": 16, "maxLength": 16 }, "simulationId": { "type": [ "string", "null" ], "minLength": 24, "maxLength": 24 }, "issueId": { "type": [ "string", "null" ], "minLength": 24, "maxLength": 24 }, "value": { "type": "number", "minimum": 0, "maximum": 1 }, "passed": { "type": "boolean" }, "feedback": { "type": "string" }, "error": { "type": [ "string", "null" ], "minLength": 1 }, "errored": { "type": "boolean" }, "duration": { "type": "integer", "minimum": 0 }, "tokens": { "type": "integer", "minimum": 0 }, "cost": { "type": "integer", "minimum": 0 }, "draftedAt": { "type": [ "string", "null" ], "format": "date-time" }, "annotatorId": { "type": [ "string", "null" ], "minLength": 24, "maxLength": 24 }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" }, "source": { "type": "string", "enum": [ "annotation" ] }, "sourceId": { "anyOf": [ { "type": "string", "enum": [ "UI", "API", "SYSTEM" ] }, { "type": "string", "minLength": 24, "maxLength": 24 } ] }, "metadata": { "type": "object", "properties": { "rawFeedback": { "type": "string" }, "messageIndex": { "type": "integer", "minimum": 0 }, "partIndex": { "type": "integer", "minimum": 0 }, "startOffset": { "type": "integer", "minimum": 0 }, "endOffset": { "type": "integer", "minimum": 0 }, "textFormat": { "type": "string", "enum": [ "pretty-json" ] } }, "required": [ "rawFeedback" ] } }, "required": [ "id", "organizationId", "projectId", "sessionId", "traceId", "spanId", "simulationId", "issueId", "value", "passed", "feedback", "error", "errored", "duration", "tokens", "cost", "draftedAt", "annotatorId", "createdAt", "updatedAt", "source", "sourceId", "metadata" ] }, "CreateAnnotationBody": { "type": "object", "properties": { "simulationId": { "type": [ "string", "null" ], "minLength": 24, "maxLength": 24, "default": null }, "issueId": { "type": [ "string", "null" ], "minLength": 24, "maxLength": 24, "default": null }, "value": { "type": "number", "minimum": 0, "maximum": 1 }, "passed": { "type": "boolean" }, "feedback": { "type": "string", "minLength": 1 }, "anchor": { "type": "object", "properties": { "messageIndex": { "type": "integer", "minimum": 0 }, "partIndex": { "type": "integer", "minimum": 0 }, "startOffset": { "type": "integer", "minimum": 0 }, "endOffset": { "type": "integer", "minimum": 0 }, "textFormat": { "type": "string", "enum": [ "pretty-json" ] } } }, "trace": { "$ref": "#/components/schemas/TraceRef" } }, "required": [ "value", "passed", "feedback", "trace" ] }, "ApiKey": { "type": "object", "properties": { "id": { "type": "string", "description": "Stable API-key identifier." }, "organizationId": { "type": "string", "description": "Organization that owns this API key." }, "name": { "type": "string", "description": "Human-readable name." }, "token": { "type": "string", "description": "The full API key token. Returned by create / get / update — store it securely; treat it as a password." }, "lastUsedAt": { "type": [ "string", "null" ], "description": "ISO-8601 timestamp of the most recent successful authentication. `null` until first use." }, "deletedAt": { "type": [ "string", "null" ], "description": "ISO-8601 timestamp at which the key was revoked. `null` while the key is active." }, "createdAt": { "type": "string", "description": "ISO-8601 timestamp of creation." }, "updatedAt": { "type": "string", "description": "ISO-8601 timestamp of the last metadata update (rename, revoke, last-used touch)." } }, "required": [ "id", "organizationId", "name", "token", "lastUsedAt", "deletedAt", "createdAt", "updatedAt" ] }, "CreateApiKeyBody": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "description": "Human-readable name for the API key. Used to distinguish keys in the UI." } }, "required": [ "name" ] }, "ApiKeyList": { "type": "object", "properties": { "apiKeys": { "type": "array", "items": { "$ref": "#/components/schemas/ApiKeyListItem" } } }, "required": [ "apiKeys" ] }, "ApiKeyListItem": { "type": "object", "properties": { "id": { "type": "string", "description": "Stable API-key identifier." }, "organizationId": { "type": "string", "description": "Organization that owns this API key." }, "name": { "type": "string", "description": "Human-readable name." }, "token": { "type": "string", "description": "Masked token preview safe to display in lists. Use `GET /api-keys/{id}` to retrieve the full token." }, "lastUsedAt": { "type": [ "string", "null" ], "description": "ISO-8601 timestamp of the most recent successful authentication. `null` until first use." }, "deletedAt": { "type": [ "string", "null" ], "description": "ISO-8601 timestamp at which the key was revoked. `null` while the key is active." }, "createdAt": { "type": "string", "description": "ISO-8601 timestamp of creation." }, "updatedAt": { "type": "string", "description": "ISO-8601 timestamp of the last metadata update." } }, "required": [ "id", "organizationId", "name", "token", "lastUsedAt", "deletedAt", "createdAt", "updatedAt" ] }, "UpdateApiKeyBody": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "description": "New human-readable name for the API key." } }, "required": [ "name" ] }, "AccountResponse": { "type": "object", "properties": { "user": { "$ref": "#/components/schemas/AccountUser" }, "organization": { "$ref": "#/components/schemas/AccountOrganization" }, "role": { "type": [ "string", "null" ], "enum": [ "owner", "admin", "member", null ], "description": "Caller's role in the organization. `null` for API-key callers (no real user behind the credential)." } }, "required": [ "user", "organization", "role" ] }, "AccountUser": { "type": [ "object", "null" ], "properties": { "id": { "type": "string", "description": "Stable user identifier across the API." }, "email": { "type": "string", "description": "Verified email address of the authenticated user." }, "name": { "type": [ "string", "null" ], "description": "Display name, when set. `null` until the user completes onboarding." }, "image": { "type": [ "string", "null" ], "description": "Profile image URL, when set." } }, "required": [ "id", "email", "name", "image" ], "description": "The user the request is acting on behalf of. `null` for API-key callers — API keys are org-scoped, not user-scoped." }, "AccountOrganization": { "type": "object", "properties": { "id": { "type": "string", "description": "Stable organization identifier across the API." }, "name": { "type": "string", "description": "Human-readable organization name." }, "slug": { "type": "string", "description": "URL-safe slug. Regenerated when the organization is renamed — don't use it as a stable key." } }, "required": [ "id", "name", "slug" ], "description": "Organization the request is scoped to." }, "MemberList": { "type": "object", "properties": { "members": { "type": "array", "items": { "$ref": "#/components/schemas/Member" } } }, "required": [ "members" ] }, "Member": { "oneOf": [ { "$ref": "#/components/schemas/ActiveMember" }, { "$ref": "#/components/schemas/InvitedMember" } ], "discriminator": { "propertyName": "status", "mapping": { "active": "#/components/schemas/ActiveMember", "invited": "#/components/schemas/InvitedMember" } } }, "ActiveMember": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "active" ], "description": "Discriminator for confirmed members — the user has accepted their invitation and joined the org." }, "id": { "type": "string", "description": "Stable membership identifier. Use this to address the row in update/remove endpoints." }, "organizationId": { "type": "string", "description": "Organization this membership belongs to." }, "userId": { "type": "string", "description": "Identifier of the user the membership represents." }, "role": { "type": "string", "enum": [ "owner", "admin", "member" ], "description": "Member's role within the organization." }, "name": { "type": [ "string", "null" ], "description": "Display name of the user. `null` if the user hasn't completed onboarding." }, "email": { "type": "string", "description": "User's email address, verified at signup." }, "image": { "type": [ "string", "null" ], "description": "User's profile image URL, when set." }, "joinedAt": { "type": "string", "description": "ISO-8601 timestamp at which the user joined the organization." } }, "required": [ "status", "id", "organizationId", "userId", "role", "name", "email", "image", "joinedAt" ] }, "InvitedMember": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "invited" ], "description": "Discriminator for pending invitations — the invitee hasn't accepted yet, so no user record exists." }, "id": { "type": "string", "description": "Stable invitation identifier. Distinct from membership ids." }, "organizationId": { "type": "string", "description": "Organization the invitation grants access to." }, "userId": { "type": "null", "description": "Always `null` — no user record exists until the invitation is accepted." }, "role": { "type": [ "string", "null" ], "enum": [ "owner", "admin", "member", null ], "description": "Role the invitee will get once they accept. `null` means the default (`member`)." }, "name": { "type": "null", "description": "Always `null` — no user record exists yet." }, "email": { "type": "string", "description": "Email address the invitation was sent to." }, "image": { "type": "null", "description": "Always `null` — no user record exists yet." }, "invitedAt": { "type": "string", "description": "ISO-8601 timestamp at which the invitation was created." }, "expiresAt": { "type": "string", "description": "ISO-8601 timestamp at which the invitation expires." }, "inviterId": { "type": "string", "description": "User id of the member who issued the invitation." } }, "required": [ "status", "id", "organizationId", "userId", "role", "name", "email", "image", "invitedAt", "expiresAt", "inviterId" ] }, "InviteMemberBody": { "type": "object", "properties": { "email": { "type": "string", "format": "email", "description": "Email address to invite. The invitee receives an accept link by email." }, "role": { "type": "string", "enum": [ "owner", "admin", "member" ], "description": "Role to grant on acceptance. Defaults to `member` when omitted." } }, "required": [ "email" ] }, "UpdateMemberRoleBody": { "type": "object", "properties": { "role": { "type": "string", "enum": [ "admin", "member" ], "description": "New role. Owners cannot be changed via this endpoint — owner-transfer happens on the web." } }, "required": [ "role" ] } }, "parameters": {} }, "paths": { "/health": { "get": { "operationId": "health.get", "tags": [ "Health" ], "summary": "Health check", "responses": { "200": { "description": "Service is healthy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HealthResponse" } } } } } } }, "/.well-known/oauth-protected-resource": { "get": { "operationId": "wellKnown.oauthProtectedResource", "tags": [ "Well-known" ], "summary": "OAuth protected resource metadata", "description": "RFC 9728 metadata document advertising the authorization server(s) trusted to issue access tokens for this API.", "responses": { "200": { "description": "Protected resource metadata", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OAuthProtectedResourceMetadata" } } } } } } }, "/v1/projects": { "post": { "operationId": "projects.create", "tags": [ "Projects" ], "summary": "Create project", "description": "Creates a new project within the organization.", "security": [ { "ApiKeyAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateProjectBody" } } } }, "responses": { "201": { "description": "Project created successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Project" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } }, "get": { "operationId": "projects.list", "tags": [ "Projects" ], "summary": "List projects", "description": "Returns all projects in the organization.", "security": [ { "ApiKeyAuth": [] } ], "responses": { "200": { "description": "List of projects", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProjectList" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/v1/projects/{projectSlug}": { "get": { "operationId": "projects.get", "tags": [ "Projects" ], "summary": "Get project", "description": "Returns a single project by slug.", "security": [ { "ApiKeyAuth": [] } ], "parameters": [ { "schema": { "type": "string", "description": "Project slug (human-readable identifier)" }, "required": true, "description": "Project slug (human-readable identifier)", "name": "projectSlug", "in": "path" } ], "responses": { "200": { "description": "Project details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Project" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } }, "patch": { "operationId": "projects.update", "tags": [ "Projects" ], "summary": "Update project", "description": "Updates a project's name and/or description.", "security": [ { "ApiKeyAuth": [] } ], "parameters": [ { "schema": { "type": "string", "description": "Project slug (human-readable identifier)" }, "required": true, "description": "Project slug (human-readable identifier)", "name": "projectSlug", "in": "path" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateProjectBody" } } } }, "responses": { "200": { "description": "Updated project", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Project" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } }, "delete": { "operationId": "projects.delete", "tags": [ "Projects" ], "summary": "Delete project", "description": "Soft-deletes a project by slug.", "security": [ { "ApiKeyAuth": [] } ], "parameters": [ { "schema": { "type": "string", "description": "Project slug (human-readable identifier)" }, "required": true, "description": "Project slug (human-readable identifier)", "name": "projectSlug", "in": "path" } ], "responses": { "204": { "description": "Project deleted successfully" }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/v1/projects/{projectSlug}/scores": { "post": { "operationId": "scores.create", "tags": [ "Scores" ], "summary": "Create project score", "description": "Creates a score against a target trace. The trace is resolved by explicit id (`trace.by = \"id\"`) or by a filter set (`trace.by = \"filters\"`, exactly one match required). Annotations use the separate `/annotations` endpoint.", "security": [ { "ApiKeyAuth": [] } ], "parameters": [ { "schema": { "type": "string", "description": "Project slug (human-readable identifier)" }, "required": true, "description": "Project slug (human-readable identifier)", "name": "projectSlug", "in": "path" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateScoreBody" } } } }, "responses": { "201": { "description": "Score created successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ScoreResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/v1/projects/{projectSlug}/annotations": { "post": { "operationId": "annotations.create", "tags": [ "Annotations" ], "summary": "Create project annotation", "description": "Creates a published annotation score against a target trace. The trace is resolved by explicit id (`trace.by = \"id\"`) or by a filter set (`trace.by = \"filters\"`, exactly one match required).", "security": [ { "ApiKeyAuth": [] } ], "parameters": [ { "schema": { "type": "string", "description": "Project slug (human-readable identifier)" }, "required": true, "description": "Project slug (human-readable identifier)", "name": "projectSlug", "in": "path" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateAnnotationBody" } } } }, "responses": { "201": { "description": "Annotation created successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AnnotationScoreResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/v1/api-keys": { "post": { "tags": [ "API Keys" ], "x-fern-sdk-group-name": "apiKeys", "x-fern-sdk-method-name": "create", "summary": "Generate API key", "description": "Generates a new API key for the organization. The token is only returned once — store it securely.", "security": [ { "ApiKeyAuth": [] } ], "operationId": "createApiKey", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateApiKeyBody" } } } }, "responses": { "201": { "description": "API key generated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiKey" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } }, "get": { "tags": [ "API Keys" ], "x-fern-sdk-group-name": "apiKeys", "x-fern-sdk-method-name": "list", "summary": "List API keys", "description": "Returns all API keys for the organization. Tokens are not included in the list response.", "security": [ { "ApiKeyAuth": [] } ], "operationId": "listApiKeys", "responses": { "200": { "description": "List of API keys", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiKeyList" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/v1/api-keys/{id}": { "get": { "tags": [ "API Keys" ], "x-fern-sdk-group-name": "apiKeys", "x-fern-sdk-method-name": "get", "summary": "Get API key", "description": "Returns a single API key including the full unmasked `token`. Useful for retrieving a stored token by id without rotating it.", "security": [ { "ApiKeyAuth": [] } ], "operationId": "getApiKey", "parameters": [ { "schema": { "type": "string", "description": "Resource ID" }, "required": true, "description": "Resource ID", "name": "id", "in": "path" } ], "responses": { "200": { "description": "API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiKey" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } }, "patch": { "tags": [ "API Keys" ], "x-fern-sdk-group-name": "apiKeys", "x-fern-sdk-method-name": "update", "summary": "Update API key", "description": "Renames an API key. The token itself is immutable — use create + revoke if you need a new value.", "security": [ { "ApiKeyAuth": [] } ], "operationId": "updateApiKey", "parameters": [ { "schema": { "type": "string", "description": "Resource ID" }, "required": true, "description": "Resource ID", "name": "id", "in": "path" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateApiKeyBody" } } } }, "responses": { "200": { "description": "API key updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiKey" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } }, "delete": { "tags": [ "API Keys" ], "x-fern-sdk-group-name": "apiKeys", "x-fern-sdk-method-name": "revoke", "summary": "Revoke API key", "description": "Soft-deletes an API key, immediately invalidating it.", "security": [ { "ApiKeyAuth": [] } ], "operationId": "revokeApiKey", "parameters": [ { "schema": { "type": "string", "description": "Resource ID" }, "required": true, "description": "Resource ID", "name": "id", "in": "path" } ], "responses": { "204": { "description": "API key revoked" }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/v1/account": { "get": { "tags": [ "Account" ], "x-fern-sdk-group-name": "account", "x-fern-sdk-method-name": "get", "summary": "Get account", "description": "Returns the caller's account snapshot: the organization the request is scoped to, plus the user record and their role when the request was made by a real user (OAuth). API-key callers receive `user: null` and `role: null` because API keys aren't tied to a specific user.", "security": [ { "ApiKeyAuth": [] } ], "operationId": "getAccount", "responses": { "200": { "description": "Account snapshot", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AccountResponse" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/v1/members": { "get": { "tags": [ "Members" ], "x-fern-sdk-group-name": "members", "x-fern-sdk-method-name": "list", "summary": "List members", "description": "Returns every active member of the caller's organization with their role and user details.", "security": [ { "ApiKeyAuth": [] } ], "operationId": "listMembers", "responses": { "200": { "description": "List of members", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MemberList" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } }, "post": { "tags": [ "Members" ], "x-fern-sdk-group-name": "members", "x-fern-sdk-method-name": "invite", "summary": "Invite a member", "description": "Issues an invitation to join the caller's organization. The invitee receives an accept link by email and becomes a member once they accept. The response is the pending invitation record. Requires OAuth authentication (API-key callers can't act on behalf of a specific user).", "security": [ { "ApiKeyAuth": [] } ], "operationId": "inviteMember", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InviteMemberBody" } } } }, "responses": { "201": { "description": "Invitation created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InvitedMember" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/v1/members/{id}": { "get": { "tags": [ "Members" ], "x-fern-sdk-group-name": "members", "x-fern-sdk-method-name": "get", "summary": "Get member", "description": "Returns a single member of the caller's organization, including their role and user details.", "security": [ { "ApiKeyAuth": [] } ], "operationId": "getMember", "parameters": [ { "schema": { "type": "string", "description": "Resource ID" }, "required": true, "description": "Resource ID", "name": "id", "in": "path" } ], "responses": { "200": { "description": "Member", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ActiveMember" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } }, "patch": { "tags": [ "Members" ], "x-fern-sdk-group-name": "members", "x-fern-sdk-method-name": "update", "summary": "Update a member", "description": "Updates a member of the caller's organization. Today only the role is mutable. The caller must be an admin or owner; owners cannot be demoted via this endpoint. Requires OAuth authentication.", "security": [ { "ApiKeyAuth": [] } ], "operationId": "updateMember", "parameters": [ { "schema": { "type": "string", "description": "Resource ID" }, "required": true, "description": "Resource ID", "name": "id", "in": "path" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateMemberRoleBody" } } } }, "responses": { "200": { "description": "Member with the updated role", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ActiveMember" } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } }, "delete": { "tags": [ "Members" ], "x-fern-sdk-group-name": "members", "x-fern-sdk-method-name": "remove", "summary": "Remove a member", "description": "Removes a member from the caller's organization. Self-removal is rejected — use the org-leave flow on the web. Requires OAuth authentication.", "security": [ { "ApiKeyAuth": [] } ], "operationId": "removeMember", "parameters": [ { "schema": { "type": "string", "description": "Resource ID" }, "required": true, "description": "Resource ID", "name": "id", "in": "path" } ], "responses": { "204": { "description": "Member removed" }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } } }, "webhooks": {} }