openapi: 3.2.0 info: title: V12 Steers API version: 2.0.0 description: Findings, runs and context documents of one V12 organization. Every path but /me sits under /orgs/{org}, where {org} is the organization's slug (GET /me returns it); a token reaches only its own organization, and any other slug answers 404. servers: - url: https://v12.sh/api/v2 tags: - name: Steers paths: /orgs/{org}/steers: get: operationId: listSteers summary: List Steers description: 'Organization-wide Steer documents that guide runs and Autopilot rules. Lists active Steers by default; archived: true lists only archived Steers.' tags: - Steers security: - bearer: [] - oauth2: - repos:read x-mcp-tool: list_steers parameters: - name: org in: path required: true description: Organization slug; must be the token's organization. schema: type: string - name: archived in: query required: false schema: default: false type: boolean responses: '200': description: List Steers content: application/json: schema: type: object properties: nextCursor: anyOf: - type: string - type: 'null' items: type: array items: type: object properties: slug: type: string title: type: string emoji: type: string revision: type: integer minimum: -9007199254740991 maximum: 9007199254740991 archivedAt: anyOf: - type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ - type: 'null' description: Archive time, or null while active. webUrl: type: string required: - slug - title - emoji - revision - archivedAt - webUrl additionalProperties: false required: - nextCursor - items additionalProperties: false '400': description: The request is invalid content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '401': description: Missing or invalid bearer token content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '403': description: The token lacks a scope, or its user lacks a permission content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '404': description: Not found in the token organization content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '409': description: The request conflicts with the current state content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '429': description: Rate limited; see Retry-After content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '503': description: Temporarily unavailable content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' post: operationId: createSteer summary: Create a Steer description: Create an organization Steer with a title, emoji and instructions. The returned slug is its stable address. Repeating this request creates another Steer; it does not attach to Autopilot rules. tags: - Steers security: - bearer: [] - oauth2: - steers:write x-mcp-tool: create_steer parameters: - name: org in: path required: true description: Organization slug; must be the token's organization. schema: type: string requestBody: required: true content: application/json: schema: type: object additionalProperties: false properties: title: type: string minLength: 1 maxLength: 120 emoji: type: string minLength: 1 instructions: type: string maxLength: 65536 required: - title - emoji - instructions responses: '201': description: Create a Steer content: application/json: schema: type: object properties: slug: type: string title: type: string emoji: type: string revision: type: integer minimum: -9007199254740991 maximum: 9007199254740991 archivedAt: anyOf: - type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ - type: 'null' description: Archive time, or null while active. webUrl: type: string instructions: type: string required: - slug - title - emoji - revision - archivedAt - webUrl - instructions additionalProperties: false '400': description: The request is invalid content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '401': description: Missing or invalid bearer token content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '403': description: The token lacks a scope, or its user lacks a permission content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '404': description: Not found in the token organization content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '409': description: The request conflicts with the current state content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '413': description: The body exceeds 1 MiB content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '415': description: The body is not application/json content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '429': description: Rate limited; see Retry-After content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '503': description: Temporarily unavailable content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' /orgs/{org}/steers/{steer}: get: operationId: getSteer summary: Get a Steer description: One active or archived Steer by slug, including its instructions and archive status. Archived Steers remain readable for historical references. tags: - Steers security: - bearer: [] - oauth2: - repos:read x-mcp-tool: get_steer parameters: - name: org in: path required: true description: Organization slug; must be the token's organization. schema: type: string - name: steer in: path required: true schema: type: string minLength: 1 maxLength: 200 description: Steer slug. responses: '200': description: Get a Steer content: application/json: schema: type: object properties: slug: type: string title: type: string emoji: type: string revision: type: integer minimum: -9007199254740991 maximum: 9007199254740991 archivedAt: anyOf: - type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ - type: 'null' description: Archive time, or null while active. webUrl: type: string instructions: type: string required: - slug - title - emoji - revision - archivedAt - webUrl - instructions additionalProperties: false '400': description: The request is invalid content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '401': description: Missing or invalid bearer token content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '403': description: The token lacks a scope, or its user lacks a permission content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '404': description: Not found in the token organization content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '409': description: The request conflicts with the current state content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '429': description: Rate limited; see Retry-After content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '503': description: Temporarily unavailable content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' patch: operationId: updateSteer summary: Edit a Steer description: Update the supplied fields of an active Steer, preserving omitted fields and its slug. Instructions changes advance its revision; existing run snapshots stay unchanged. Restore an archived Steer before editing it. tags: - Steers security: - bearer: [] - oauth2: - steers:write x-mcp-tool: update_steer parameters: - name: org in: path required: true description: Organization slug; must be the token's organization. schema: type: string - name: steer in: path required: true schema: type: string minLength: 1 maxLength: 200 description: Steer slug. requestBody: required: true content: application/json: schema: type: object additionalProperties: false properties: title: type: string minLength: 1 maxLength: 120 emoji: type: string minLength: 1 instructions: type: string maxLength: 65536 required: [] responses: '200': description: Edit a Steer content: application/json: schema: type: object properties: slug: type: string title: type: string emoji: type: string revision: type: integer minimum: -9007199254740991 maximum: 9007199254740991 archivedAt: anyOf: - type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ - type: 'null' description: Archive time, or null while active. webUrl: type: string instructions: type: string required: - slug - title - emoji - revision - archivedAt - webUrl - instructions additionalProperties: false '400': description: The request is invalid content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '401': description: Missing or invalid bearer token content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '403': description: The token lacks a scope, or its user lacks a permission content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '404': description: Not found in the token organization content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '409': description: The request conflicts with the current state content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '413': description: The body exceeds 1 MiB content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '415': description: The body is not application/json content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '429': description: Rate limited; see Retry-After content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '503': description: Temporarily unavailable content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' delete: operationId: archiveSteer summary: Archive a Steer description: Archive a Steer and detach it from every Autopilot rule. Rules keep their active or paused state; a rule with no remaining Steers uses its default review. New runs refuse the Steer, while finding tags and queued, running and completed run snapshots remain intact. Repeating archive is safe. tags: - Steers security: - bearer: [] - oauth2: - steers:write x-mcp-tool: archive_steer parameters: - name: org in: path required: true description: Organization slug; must be the token's organization. schema: type: string - name: steer in: path required: true schema: type: string minLength: 1 maxLength: 200 description: Steer slug. responses: '200': description: Archive a Steer content: application/json: schema: type: object properties: slug: type: string title: type: string emoji: type: string revision: type: integer minimum: -9007199254740991 maximum: 9007199254740991 archivedAt: anyOf: - type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ - type: 'null' description: Archive time, or null while active. webUrl: type: string instructions: type: string required: - slug - title - emoji - revision - archivedAt - webUrl - instructions additionalProperties: false '400': description: The request is invalid content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '401': description: Missing or invalid bearer token content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '403': description: The token lacks a scope, or its user lacks a permission content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '404': description: Not found in the token organization content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '409': description: The request conflicts with the current state content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '429': description: Rate limited; see Retry-After content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '503': description: Temporarily unavailable content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' /orgs/{org}/steers/{steer}/restore: post: operationId: restoreSteer summary: Restore a Steer description: Make an archived Steer available for edits and new runs again, keeping its slug and revision. Former Autopilot attachments are not restored; add them again separately. Repeating restore is safe. tags: - Steers security: - bearer: [] - oauth2: - steers:write x-mcp-tool: restore_steer parameters: - name: org in: path required: true description: Organization slug; must be the token's organization. schema: type: string - name: steer in: path required: true schema: type: string minLength: 1 maxLength: 200 description: Steer slug. requestBody: required: true content: application/json: schema: type: object additionalProperties: false properties: {} required: [] responses: '200': description: Restore a Steer content: application/json: schema: type: object properties: slug: type: string title: type: string emoji: type: string revision: type: integer minimum: -9007199254740991 maximum: 9007199254740991 archivedAt: anyOf: - type: string format: date-time pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ - type: 'null' description: Archive time, or null while active. webUrl: type: string instructions: type: string required: - slug - title - emoji - revision - archivedAt - webUrl - instructions additionalProperties: false '400': description: The request is invalid content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '401': description: Missing or invalid bearer token content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '403': description: The token lacks a scope, or its user lacks a permission content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '404': description: Not found in the token organization content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '409': description: The request conflicts with the current state content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '413': description: The body exceeds 1 MiB content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '415': description: The body is not application/json content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '429': description: Rate limited; see Retry-After content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' '503': description: Temporarily unavailable content: application/json: schema: $ref: '#/components/schemas/ApiErrorEnvelope' components: schemas: ApiErrorEnvelope: type: object properties: error: type: object properties: code: type: string enum: - invalid_request - repository_required - unauthenticated - insufficient_credits - spend_cap_reached - insufficient_scope - forbidden - not_found - repository_not_visible - repository_not_added - method_not_allowed - position_unavailable - decision_active - conflict - price_exceeds_max - quote_stale - change_refused - nothing_to_review - repository_not_runnable - idempotency_key_reused - api_version_retired - payload_too_large - unsupported_media_type - rate_limited - internal_error - upstream_error - platform_unavailable - repository_access_unavailable - rate_limit_unavailable - public_api_disabled message: type: string details: type: object propertyNames: type: string additionalProperties: {} required: - code - message additionalProperties: false requestId: type: string required: - error - requestId additionalProperties: false securitySchemes: bearer: type: http scheme: bearer description: A personal access token (v12p_…) or an OAuth access token (v12a_…). oauth2: type: oauth2 flows: authorizationCode: authorizationUrl: https://v12.sh/oauth/authorize tokenUrl: https://v12.sh/api/oauth/token refreshUrl: https://v12.sh/api/oauth/token scopes: user:read: 'The member directory: usernames, emails and roles. Any key reads its own account, organization and credit balance without it.' repos:read: Repositories, branches, pull requests, tags and Steer instructions. repos:write: Add public repositories to the workspace; owners can also add private repositories granted by GitHub, create repositories V12 hosts and push code to them. steers:write: Create, edit, archive and restore Steers. Archiving detaches them from Autopilot rules; finding tags and run history are kept. runs:read: Runs, their progress and context documents. runs:write: Estimate and start runs; add or archive context documents. runs:manage: Cancel runs. runs:share: Create, change and revoke guest links that open a run to people outside the organization. findings:read: 'The inbox: findings, their status, reports and comments.' findings:write: Change status, comment and update triage decisions.