openapi: 3.0.2 servers: - url: /api security: - {} info: version: 3.18.4 title: GripMock API Schema description: | REST control plane for [GripMock](https://github.com/bavix/gripmock), a gRPC mock server. Use it to load stubs, ask which stub a request would match, read call history and assert call counts — all while the server keeps running. **Base URL.** Every path below is relative to `/api`, served on the HTTP port (`4771` by default). The gRPC port (`4770`) and the ConnectRPC/gRPC-web gateway (`4769`) are separate. **Sessions.** Send `X-Gripmock-Session: ` to scope a request to one session. Stubs created within a session are visible only there, and call history is kept apart. Without the header the request works against the global scope. **Not in this document.** `POST /api/mcp` speaks the Model Context Protocol for agent tooling, and `GET /metrics` — outside `/api` — serves Prometheus metrics. contact: name: Maksim Babichev url: https://github.com/bavix/gripmock-openapi license: name: MIT url: https://github.com/bavix/gripmock-openapi/blob/master/LICENSE tags: - name: healthcheck description: Liveness and readiness probes. - name: dashboard description: Aggregate counters and build/runtime information behind the web UI. - name: sessions description: Session IDs currently known to the server. - name: services description: Services and methods GripMock can serve, across every descriptor source. - name: stubs description: >- Create, list, search and delete stubs, and inspect why one matched. Send `X-Gripmock-Session: ` to scope the call to one session; without it the request works against the global scope. - name: history description: >- Calls the server has answered, newest first. Send `X-Gripmock-Session: ` to scope the call to one session; without it the request works against the global scope. - name: verify description: >- Assert how many times a method was called. Send `X-Gripmock-Session: ` to scope the call to one session; without it the request works against the global scope. - name: descriptors description: Load a compiled `FileDescriptorSet` into a running server. paths: # healthcheck /health/liveness: get: tags: - healthcheck summary: Liveness check description: This endpoint indicates that the service is alive and ready to handle requests operationId: liveness responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/MessageOK' '400': description: Bad Request '500': description: Internal Server Error /health/readiness: get: tags: - healthcheck summary: Readiness check description: The test indicates readiness to receive traffic operationId: readiness responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/MessageOK' '400': description: Bad Request '500': description: Internal Server Error # dashboard /dashboard: get: tags: - dashboard summary: Dashboard aggregate payload description: Returns combined dashboard counters, runtime metadata, and process state in one response. operationId: dashboard responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/Dashboard' '500': description: Internal Server Error /dashboard/overview: get: tags: - dashboard summary: Dashboard overview metrics description: Returns lightweight aggregate counters for admin UI dashboard. operationId: dashboardOverview responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/DashboardOverview' '500': description: Internal Server Error /dashboard/info: get: tags: - dashboard summary: Dashboard runtime and build info description: Returns GripMock build metadata and current runtime process information. operationId: dashboardInfo responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/DashboardInfo' '500': description: Internal Server Error # sessions /sessions: get: tags: - sessions summary: Session options description: Returns distinct non-empty session IDs available in current stubs. operationId: sessionsList responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/Sessions' '500': description: Internal Server Error # services reflection /services: get: tags: - services summary: Services description: List of registered services operationId: servicesList responses: '200': description: Successful operation content: application/json: schema: type: array items: $ref: '#/components/schemas/Service' '404': description: No services found '500': description: Internal Server Error /services/{serviceID}/methods: get: tags: - services summary: Service methods description: List of registered service methods operationId: serviceMethodsList parameters: - name: serviceID in: path description: ID of service required: true schema: type: string responses: '200': description: Successful operation content: application/json: schema: type: array items: $ref: '#/components/schemas/Method' '400': description: Invalid service ID '404': description: Service not found '500': description: Internal Server Error /services/{serviceID}/methods/{methodID}: get: tags: - services summary: Service method details description: Returns exact metadata for one method (by short name or full method id). operationId: serviceMethodGet parameters: - name: serviceID in: path description: Full service name (e.g. helloworld.Greeter) required: true schema: type: string - name: methodID in: path description: Method short name (e.g. SayHello) or full id (e.g. helloworld.Greeter/SayHello) required: true schema: type: string responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/Method' '400': description: Invalid service or method id '404': description: Service or method not found '500': description: Internal Server Error /services/{serviceID}: get: tags: - services summary: Service details description: Returns exact metadata for one service including all methods and streaming capabilities. operationId: serviceGet parameters: - name: serviceID in: path description: Full service name (e.g. helloworld.Greeter) required: true schema: type: string responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/Service' '400': description: Invalid service ID '404': description: Service not found '500': description: Internal Server Error delete: tags: - services summary: Remove service description: Removes a service added via POST /descriptors. Services from startup (proto path) cannot be removed. operationId: deleteService parameters: - name: serviceID in: path description: Full service name (e.g. helloworld.Greeter) required: true schema: type: string responses: '204': description: Service removed successfully '404': description: Service not found (not added via REST or already removed) '500': description: Internal Server Error # stubs /stubs/used: get: tags: - stubs summary: Getting a list of used stubs description: The list is needed to quickly find used stubs operationId: listUsedStubs responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/StubList' '404': description: No used stubs found '500': description: Internal Server Error /stubs/unused: get: tags: - stubs summary: Getting a list of unused stubs description: The list is needed to quickly find unused stubs operationId: listUnusedStubs responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/StubList' '404': description: No unused stubs found '500': description: Internal Server Error /stubs: get: tags: - stubs summary: Getting a list of stubs description: The list of stubs is required to view all added stubs. Use source query param to filter by source. operationId: listStubs parameters: - name: source in: query description: Filter by source (file, rest, mcp, proxy) required: false schema: type: string - name: service in: query description: Filter by service name (exact match) required: false schema: type: string - name: method in: query description: Filter by method name (exact match) required: false schema: type: string - name: session in: query description: Filter by session ID (empty means global stubs) required: false schema: type: string - name: q in: query description: Case-insensitive substring search over service, method and stub ID required: false schema: type: string - name: matcher in: query description: >- Filter by matcher kind(s) present on the stub input. Comma-separated for OR semantics (e.g. "glob,anyOf"). Valid kinds: equals, contains, matches, glob, anyOf. required: false schema: type: string - name: limit in: query description: Maximum number of returned stubs required: false schema: type: integer minimum: 1 - name: offset in: query description: Number of stubs to skip before returning results required: false schema: type: integer minimum: 0 - name: sort in: query description: Sort order for result list required: false schema: type: string responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/StubList' '400': description: >- A query parameter could not be parsed, for example a non-numeric `limit`. '404': description: No stubs found '500': description: Internal Server Error post: tags: - stubs summary: Add a new stub to the store description: Creates a new stub or multiple stubs and adds them to the storage operationId: addStub responses: '200': description: Successful operation content: application/json: schema: oneOf: - $ref: '#/components/schemas/ListID' '400': description: >- The payload is not valid JSON, or the stub failed validation — for example `input` and `inputs` both set, or `output` carrying both the unary side and `stream`. The body holds an `error` string naming the field. '500': description: Internal Server Error requestBody: description: Create a new stub in the store required: true content: application/json: schema: oneOf: - $ref: '#/components/schemas/StubList' - $ref: '#/components/schemas/Stub' delete: tags: - stubs summary: Remove all stubs description: Completely clears the stub storage operationId: purgeStubs responses: '204': description: Successful operation '400': description: Bad Request '500': description: Internal Server Error /stubs/batchDelete: post: tags: - stubs summary: Deletes a batch of stubs by IDs description: Takes IDs as input and deletes them operationId: batchStubsDelete responses: '204': description: Successful operation '400': description: Invalid IDs provided '404': description: Some stubs not found '500': description: Internal Server Error requestBody: description: Delete stubs by their IDs required: true content: application/json: schema: $ref: '#/components/schemas/ListID' /stubs/validate: post: tags: - stubs summary: Validate a stub payload without persisting description: Validates one or more stubs and returns them normalized without adding to storage operationId: validateStub responses: '200': description: Successful operation content: application/json: schema: oneOf: - $ref: '#/components/schemas/StubList' '400': description: >- The payload is not valid JSON, or the stub failed validation — for example `input` and `inputs` both set, or `output` carrying both the unary side and `stream`. The body holds an `error` string naming the field. '500': description: Internal Server Error requestBody: description: Stub payload to validate required: true content: application/json: schema: oneOf: - $ref: '#/components/schemas/StubList' - $ref: '#/components/schemas/Stub' /stubs/{uuid}: get: tags: - stubs summary: Get Stub by ID description: Searches for Stub by ID operationId: findByID parameters: - name: uuid in: path description: ID of stub required: true schema: $ref: '#/components/schemas/ID' responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/Stub' '400': description: Invalid UUID format '404': description: Stub not found '500': description: Internal Server Error delete: tags: - stubs summary: Deletes stub by ID description: The method removes the stub by ID operationId: deleteStubByID parameters: - name: uuid in: path description: ID of stub required: true schema: $ref: '#/components/schemas/ID' responses: '204': description: successful operation '400': description: Invalid UUID format '404': description: Stub not found '500': description: Internal Server Error /stubs/search: post: tags: - stubs summary: Stub storage search description: Performs a search for a stub by the given conditions operationId: searchStubs responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/SearchResponse' '400': description: Invalid search criteria '422': description: Validation error '500': description: Internal Server Error requestBody: description: Search criteria including service, method, headers and data to match against stubs required: true content: application/json: schema: $ref: '#/components/schemas/SearchRequest' /stubs/inspect: post: tags: - stubs summary: Inspect stub matching decision path description: Returns detailed matching stages/candidates for a query without consuming stub times. operationId: inspectStubs responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/InspectReport' '400': description: Invalid inspect criteria '422': description: Validation error '500': description: Internal Server Error requestBody: description: Inspect criteria including service, method, optional headers/session and input messages required: true content: application/json: schema: $ref: '#/components/schemas/InspectRequest' # history & verify /history: get: tags: - history summary: Get call history description: Returns recorded gRPC calls (when history is enabled) operationId: listHistory parameters: - name: limit in: query required: false description: Return at most N most-recent records schema: type: integer minimum: 0 - name: offset in: query required: false description: Skip the N newest records (page backward through older calls) schema: type: integer minimum: 0 - name: service in: query required: false schema: type: string description: >- Keep only calls to this fully qualified service name. - name: method in: query required: false schema: type: string description: >- Keep only calls to this method name. - name: error in: query required: false description: When true, return only calls that ended with a gRPC error schema: type: boolean responses: '200': description: List of recorded calls headers: X-Total-Count: description: Total number of records before pagination schema: type: integer content: application/json: schema: $ref: '#/components/schemas/HistoryList' '400': description: >- A query parameter could not be parsed, for example a non-numeric `limit`. '500': description: Internal Server Error /verify: post: tags: - verify summary: Verify call counts description: Asserts that a method was called a specified number of times operationId: verifyCalls responses: '200': description: Verification passed content: application/json: schema: $ref: '#/components/schemas/MessageOK' '400': description: Verification failed (wrong call count) content: application/json: schema: $ref: '#/components/schemas/VerifyError' '500': description: Internal Server Error requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/VerifyRequest' # descriptors /descriptors: get: tags: - descriptors summary: List service IDs from REST-added descriptors description: Returns service IDs (e.g. helloworld.Greeter) added via POST /descriptors. Use DELETE /services/{serviceID} to remove. operationId: listDescriptors responses: '200': description: List of removable service IDs content: application/json: schema: $ref: '#/components/schemas/DescriptorServiceIDs' '500': description: Internal Server Error post: tags: - descriptors summary: Upload FileDescriptorSet description: Accepts binary Protocol Buffers FileDescriptorSet. Registers descriptors for dynamic service discovery. Returns service IDs for later removal via DELETE /services/{serviceID}. operationId: addDescriptors requestBody: required: true content: application/octet-stream: schema: type: string format: binary responses: '200': description: Descriptors registered successfully content: application/json: schema: $ref: '#/components/schemas/AddDescriptorsResponse' '400': description: Invalid or empty FileDescriptorSet '500': description: Internal Server Error components: schemas: # health MessageOK: type: object required: - message - time properties: message: type: string x-omitzero: false description: >- Human-readable result of the operation. time: type: string format: date-time x-omitzero: false description: >- Server time when the response was produced (RFC 3339). description: >- Generic acknowledgement. AddDescriptorsResponse: type: object required: - message - time - serviceIDs properties: message: type: string x-omitzero: false description: >- Human-readable result of the upload. time: type: string format: date-time x-omitzero: false description: >- Server time when the response was produced (RFC 3339). serviceIDs: type: array items: type: string description: Service IDs (e.g. helloworld.Greeter) registered. Use DELETE /services/{serviceID} to remove. description: >- Result of registering an uploaded FileDescriptorSet. DescriptorServiceIDs: type: object required: - serviceIDs properties: serviceIDs: type: array items: type: string description: Service IDs added via POST /descriptors # services description: >- Service IDs registered from descriptors uploaded over REST. Service: type: object required: - id - package - name - methods properties: id: type: string x-omitzero: false description: >- Fully qualified service name, used as the path segment in `/services/{serviceID}`. package: type: string x-omitzero: false description: >- Proto package the service is declared in. name: type: string x-omitzero: false description: >- Service name without the package prefix. methods: type: array items: $ref: '#/components/schemas/Method' x-omitzero: false description: >- Methods the service exposes. description: >- A gRPC service GripMock can serve. Method: type: object required: - id - name - methodType properties: id: type: string x-omitzero: false description: >- Method name, used as the path segment in `/methods/{methodID}`. name: type: string x-omitzero: false description: >- Method name as declared in the proto file. methodType: type: string description: gRPC method interaction type enum: - unary - client_streaming - server_streaming - bidi_streaming x-omitzero: false requestType: type: string description: Fully-qualified protobuf request message type responseType: type: string description: Fully-qualified protobuf response message type requestSchema: $ref: '#/components/schemas/ProtoMessageSchema' responseSchema: $ref: '#/components/schemas/ProtoMessageSchema' clientStreaming: type: boolean description: Indicates client-side streaming method x-go-type-skip-optional-pointer: true serverStreaming: type: boolean description: Indicates server-side streaming method x-go-type-skip-optional-pointer: true description: >- A method of a gRPC service. ProtoMessageSchema: type: object required: - typeName - fields properties: typeName: type: string description: Fully-qualified protobuf message type name recursiveRef: type: boolean description: True when schema expansion stopped due to recursive reference x-go-type-skip-optional-pointer: true fields: type: array items: $ref: '#/components/schemas/ProtoFieldSchema' description: >- Fields declared on the message. description: >- Shape of a proto message, as GripMock resolved it from the descriptor. ProtoFieldSchema: type: object required: - name - jsonName - number - kind - cardinality properties: name: type: string description: >- Field name as declared in the proto file (snake_case). jsonName: type: string description: >- Field name in protojson output (camelCase). number: type: integer minimum: 1 description: >- Field number from the proto definition. kind: type: string description: >- Proto kind, for example `string`, `int32`, `message`, `enum`. cardinality: type: string enum: - optional - required - repeated description: >- Whether the field is optional, required or repeated. typeName: type: string description: Referenced protobuf type for message/enum fields oneof: type: string description: Oneof group name if field belongs to oneof enumValues: type: array items: type: string description: >- Allowed value names when `kind` is `enum`. map: type: boolean x-go-type-skip-optional-pointer: true description: >- True when the field is a proto map. mapKeyKind: type: string description: >- Kind of the map key, when `map` is true. mapValueKind: type: string description: >- Kind of the map value, when `map` is true. mapValueTypeName: type: string description: >- Fully qualified type name of the map value, when it is a message or enum. message: $ref: '#/components/schemas/ProtoMessageSchema' mapValueMessage: $ref: '#/components/schemas/ProtoMessageSchema' # stubs description: >- A single field of a proto message. ID: type: string format: uuid x-go-type: uuid.UUID x-go-type-import: name: uuid path: github.com/google/uuid example: 51c50050-ec27-4dae-a583-a32ca71a1dd5 x-omitzero: false description: >- Stub identifier (UUID). ListID: type: array items: $ref: '#/components/schemas/ID' x-omitzero: false description: >- A list of stub UUIDs. StubList: type: array items: $ref: '#/components/schemas/Stub' x-omitzero: false description: >- A list of stubs. SearchRequest: type: object required: - service - method - data properties: id: $ref: '#/components/schemas/ID' service: type: string example: Gripmock x-omitzero: false description: >- Fully qualified gRPC service name. method: type: string example: SayHello x-omitzero: false description: >- gRPC method name. headers: type: object additionalProperties: type: string x-go-type-skip-optional-pointer: true description: >- Request metadata to match against stub `headers`. data: type: object x-go-type: interface{} additionalProperties: true x-omitzero: false description: >- Request body to match against stub `input`. description: >- A synthetic gRPC request. The server resolves it against the loaded stubs and returns the output of the winning stub, without performing the call. SearchResponse: type: object required: - data - error properties: headers: type: object additionalProperties: type: string x-go-type-skip-optional-pointer: true description: >- Response metadata of the matched stub. data: type: object x-go-type: interface{} additionalProperties: true x-omitzero: false description: >- Response body of the matched stub. error: type: string example: Message not found x-omitzero: false description: >- gRPC status message, empty when the stub returns data. code: type: integer format: uint32 x-go-type: codes.Code x-go-type-import: name: codes path: google.golang.org/grpc/codes example: 3 x-go-type-skip-optional-pointer: true description: >- gRPC status code. description: >- Output of the stub that won the match. CallRecord: type: object properties: service: type: string description: >- Fully qualified gRPC service name. method: type: string description: >- gRPC method name. session: type: string description: Session ID (empty = global) stubId: type: string format: uuid x-go-type: uuid.UUID x-go-type-import: name: uuid path: github.com/google/uuid description: Stub identifier timestamp: type: string format: date-time description: >- When the call was received (RFC 3339). request: type: object additionalProperties: true description: "Deprecated: use requests for streaming calls" deprecated: true requests: type: array description: Request messages for streaming calls (client stream, bidi stream) items: type: object additionalProperties: true response: type: object additionalProperties: true description: "Deprecated: use responses for streaming calls" deprecated: true responses: type: array description: Response messages for streaming calls (server stream, bidi stream) items: type: object additionalProperties: true responseHeaders: type: object description: Normalized response metadata (header+trailer) the call answered with additionalProperties: type: string x-go-type-skip-optional-pointer: true code: type: integer description: gRPC status code (e.g., 0 for OK, 5 for NotFound) error: type: string description: >- gRPC status message, empty when the call succeeded. elapsedMs: type: integer format: int64 description: Handler duration in milliseconds description: >- One gRPC call the server answered. HistoryList: type: array items: $ref: '#/components/schemas/CallRecord' description: >- A page of recorded calls, newest first. VerifyRequest: type: object required: - service - method - expectedCount properties: service: type: string description: >- Fully qualified gRPC service name. method: type: string description: >- gRPC method name. expectedCount: type: integer minimum: 0 description: >- Number of calls the method must have received. description: >- Expected number of calls to one method. VerifyError: type: object properties: message: type: string description: >- Human-readable summary of the mismatch. expected: type: integer description: >- Count the caller asked for. actual: type: integer description: >- Count actually recorded. description: >- Reported when the recorded count differs from the expectation. InspectRequest: type: object required: - service - method properties: id: $ref: '#/components/schemas/ID' service: type: string description: >- Fully qualified gRPC service name. method: type: string description: >- gRPC method name. session: type: string description: >- Session to resolve against; empty means the global scope. headers: type: object additionalProperties: true x-go-type-skip-optional-pointer: true description: >- Request metadata, matched against stub `headers`. input: type: array items: type: object additionalProperties: true x-go-type-skip-optional-pointer: true description: >- Request body, matched against stub `input`. description: >- A request to explain: the server reports every stub it considered and why each was kept or dropped. InspectStage: type: object required: - name - before - after - removed properties: name: type: string description: >- Filter applied at this step: service/method, session, times, headers, input, or the method fallback. before: type: integer description: >- Candidates entering the step. after: type: integer description: >- Candidates surviving the step. removed: type: integer description: >- Candidates dropped by the step (`before` minus `after`). description: >- One filtering step, with how many candidates entered and survived it. InspectCandidateEvent: type: object required: - stage - result properties: stage: type: string description: >- Stage the event belongs to. result: type: string description: >- Whether the candidate passed the stage, was dropped, or was selected. reason: type: string description: >- Why, when the candidate was dropped. description: >- What happened to one candidate at one stage. InspectCandidate: type: object required: - id - service - method - session - priority - times - used - specificity - score - visibleBySession - withinTimes - headersMatched - inputMatched - matched - excludedBy - events properties: id: type: string description: >- Stub UUID. service: type: string description: >- Service the stub answers. method: type: string description: >- Method the stub answers. session: type: string description: >- Session the stub belongs to; empty means global. priority: type: integer description: >- The stub `priority` value. times: type: integer description: >- Effective match limit; `0` means unlimited. used: type: integer description: >- How many times the stub has already matched in this session. specificity: type: integer description: >- How narrowly the stub describes the request. Compared first when picking a winner. score: type: number format: double description: >- Match rank plus `priority × 10`. Breaks ties between equally specific stubs. visibleBySession: type: boolean description: >- False when the stub belongs to a different session. withinTimes: type: boolean description: >- False when the stub is exhausted by its `times` limit. headersMatched: type: boolean description: >- Whether the stub `headers` matched the request metadata. inputMatched: type: boolean description: >- Whether the stub `input` matched the request body. matched: type: boolean description: >- True for the single stub that won. excludedBy: type: array items: type: string description: >- Reasons this candidate was ruled out; empty when it survived. events: type: array items: $ref: '#/components/schemas/InspectCandidateEvent' description: >- Per-stage verdicts for this candidate. description: >- A stub the server considered, with the verdict at each stage. InspectReport: type: object required: - service - method - session - matchedStubId - similarStubId - fallbackToMethod - error - stages - candidates properties: service: type: string description: >- Service that was inspected. method: type: string description: >- Method that was inspected. session: type: string description: >- Session the request was resolved against. matchedStubId: type: string description: >- UUID of the winning stub, absent when nothing matched. similarStubId: type: string description: >- Closest non-matching stub, offered as a hint when nothing matched. fallbackToMethod: type: boolean description: >- True when no stub matched the input and the search widened to any stub on the method. error: type: string description: >- Why the request could not be resolved. stages: type: array items: $ref: '#/components/schemas/InspectStage' description: >- How the candidate set narrowed, step by step. candidates: type: array items: $ref: '#/components/schemas/InspectCandidate' description: >- Every stub considered, with its verdict. description: >- Why a request matched — or did not. Stages show how the candidate set narrowed. DashboardOverview: type: object required: - totalServices - totalStubs - usedStubs - unusedStubs - totalSessions - runtimeDescriptors - totalHistory - historyErrors properties: totalServices: type: integer minimum: 0 description: >- Services currently registered, from every descriptor source. totalStubs: type: integer minimum: 0 description: >- Stubs currently in storage. usedStubs: type: integer minimum: 0 description: >- Stubs matched at least once since startup. unusedStubs: type: integer minimum: 0 description: >- Stubs never matched since startup. coveredMethods: type: integer minimum: 0 description: Number of gRPC methods that have at least one stub x-go-type-skip-optional-pointer: true totalMethods: type: integer minimum: 0 description: Total number of gRPC methods across all services x-go-type-skip-optional-pointer: true grpcAddr: type: string description: Native gRPC listen address x-go-type-skip-optional-pointer: true gatewayAddr: type: string description: ConnectRPC + gRPC-web listen address x-go-type-skip-optional-pointer: true httpAddr: type: string description: Admin REST API + UI listen address x-go-type-skip-optional-pointer: true totalSessions: type: integer minimum: 0 description: >- Sessions currently known to the server. runtimeDescriptors: type: integer minimum: 0 description: >- Descriptors uploaded over REST since startup. totalHistory: type: integer minimum: 0 description: >- Calls recorded in history. historyErrors: type: integer minimum: 0 description: >- Recorded calls that ended in a gRPC error. description: >- Aggregate counters shown on the dashboard. Sessions: type: object required: - sessions properties: sessions: type: array items: type: string description: >- Known session IDs. description: >- Session IDs currently known to the server. DashboardInfo: type: object required: - appName - version - goVersion - compiler - goos - goarch - numCPU - startedAt - uptimeSeconds - ready - historyEnabled - totalServices - totalStubs - totalSessions - runtimeDescriptors properties: appName: type: string description: >- Application name reported by the binary. version: type: string description: >- GripMock version. goVersion: type: string description: >- Go version the binary was built with. compiler: type: string description: >- Go compiler used for the build. goos: type: string description: >- Operating system the binary targets. goarch: type: string description: >- CPU architecture the binary targets. numCPU: type: integer minimum: 1 description: >- CPUs visible to the process. startedAt: type: string format: date-time description: >- When the process started (RFC 3339). uptimeSeconds: type: integer minimum: 0 description: >- Seconds since startup. ready: type: boolean description: >- Whether the server has finished loading and is answering calls. historyEnabled: type: boolean description: >- Whether call history recording is on (`HISTORY_ENABLED`). totalServices: type: integer minimum: 0 description: >- Services currently registered, from every descriptor source. totalStubs: type: integer minimum: 0 description: >- Stubs currently in storage. totalSessions: type: integer minimum: 0 description: >- Sessions currently known to the server. runtimeDescriptors: type: integer minimum: 0 description: >- Descriptors uploaded over REST since startup. description: >- Build and runtime information about this instance. Dashboard: type: object required: - appName - version - goVersion - compiler - goos - goarch - numCPU - startedAt - uptimeSeconds - ready - historyEnabled - totalServices - totalStubs - usedStubs - unusedStubs - totalSessions - runtimeDescriptors - totalHistory - historyErrors properties: appName: type: string description: >- Application name reported by the binary. version: type: string description: >- GripMock version. goVersion: type: string description: >- Go version the binary was built with. compiler: type: string description: >- Go compiler used for the build. goos: type: string description: >- Operating system the binary targets. goarch: type: string description: >- CPU architecture the binary targets. numCPU: type: integer minimum: 1 description: >- CPUs visible to the process. startedAt: type: string format: date-time description: >- When the process started (RFC 3339). uptimeSeconds: type: integer minimum: 0 description: >- Seconds since startup. ready: type: boolean description: >- Whether the server has finished loading and is answering calls. historyEnabled: type: boolean description: >- Whether call history recording is on (`HISTORY_ENABLED`). totalServices: type: integer minimum: 0 description: >- Services currently registered, from every descriptor source. totalStubs: type: integer minimum: 0 description: >- Stubs currently in storage. usedStubs: type: integer minimum: 0 description: >- Stubs matched at least once since startup. unusedStubs: type: integer minimum: 0 description: >- Stubs never matched since startup. coveredMethods: type: integer minimum: 0 description: Number of gRPC methods that have at least one stub x-go-type-skip-optional-pointer: true totalMethods: type: integer minimum: 0 description: Total number of gRPC methods across all services x-go-type-skip-optional-pointer: true grpcAddr: type: string description: Native gRPC listen address x-go-type-skip-optional-pointer: true gatewayAddr: type: string description: ConnectRPC + gRPC-web listen address x-go-type-skip-optional-pointer: true httpAddr: type: string description: Admin REST API + UI listen address x-go-type-skip-optional-pointer: true totalSessions: type: integer minimum: 0 description: >- Sessions currently known to the server. runtimeDescriptors: type: integer minimum: 0 description: >- Descriptors uploaded over REST since startup. totalHistory: type: integer minimum: 0 description: >- Calls recorded in history. historyErrors: type: integer minimum: 0 description: >- Recorded calls that ended in a gRPC error. description: >- Overview and runtime info in a single payload. Stub: type: object required: - service - method - input - output properties: id: $ref: '#/components/schemas/ID' service: type: string example: Gripmock x-omitzero: false description: >- Fully qualified gRPC service name. method: type: string example: SayHello x-omitzero: false description: >- gRPC method name, without the service prefix. priority: type: integer default: 0 description: >- Tie-breaker among equally specific stubs; higher wins. Specificity is compared first, so an `equals` stub still beats a `contains` stub with a higher priority. x-go-type-skip-optional-pointer: true used: type: boolean description: Response-only — whether the stub has matched at least once. Ignored on input. x-go-type-skip-optional-pointer: true headers: $ref: '#/components/schemas/StubHeaders' input: $ref: '#/components/schemas/StubInput' x-omitzero: false description: >- Matchers for a unary request body. Mutually exclusive with `inputs`. inputs: type: array description: >- Per-message matchers for client and bidirectional streaming. With one element it is a broadcast pattern that every message must match; with several, element N is matched against the Nth message and the counts must be equal. Mutually exclusive with `input` — a stub with both is rejected. For OR semantics use `input.anyOf`. items: $ref: '#/components/schemas/StubInput' x-go-type-skip-optional-pointer: true output: $ref: '#/components/schemas/StubOutput' x-omitzero: false options: $ref: '#/components/schemas/StubOptions' x-omitzero: true effects: type: array description: Side effects applied after successful stub match items: $ref: '#/components/schemas/StubEffect' x-go-type-skip-optional-pointer: true source: type: string description: Source of the stub (file, rest, mcp, proxy) readOnly: true x-omitzero: true description: >- A single stub: which method it answers, which requests it accepts, and what it returns. StubOptions: type: object description: Optional behavior settings for a stub properties: times: type: integer description: >- Maximum number of matches; `0` means unlimited. Once the limit is reached the stub is exhausted and stops matching, though it stays in storage. minimum: 0 default: 0 x-go-type-skip-optional-pointer: true StubEffect: type: object required: - action properties: action: type: string enum: [upsert, delete] description: >- `upsert` creates or replaces a stub, `delete` removes one. id: type: string description: >- Target stub UUID for `delete`. May be a template that renders to a UUID. x-go-type-skip-optional-pointer: true stub: type: object additionalProperties: true description: >- Stub payload for `upsert`, validated after template rendering. x-go-type-skip-optional-pointer: true description: >- Side effect applied after this stub matches — used to build multi-step flows where one call arms the next. StubInput: type: object properties: ignoreArrayOrder: type: boolean default: false x-go-type-skip-optional-pointer: true description: >- Compare arrays as sets rather than ordered sequences. Applies to this matcher block only — it is not inherited by `anyOf` elements. equals: type: object additionalProperties: true x-go-type-skip-optional-pointer: true description: >- Exact match. Every listed field must be present in the request with exactly this value, case-sensitive. Arrays compare in order unless `ignoreArrayOrder` is set. contains: type: object additionalProperties: true x-go-type-skip-optional-pointer: true description: >- Subset match. The request must carry at least these fields. Strings match on substring, arrays on containment, nested objects recursively. Extra fields in the request are ignored. matches: type: object additionalProperties: true x-go-type-skip-optional-pointer: true description: >- Regex match. Each leaf value is a Go regular expression applied to the corresponding request value. glob: type: object description: >- Glob match. Each leaf value is a shell-style pattern (`*`, `?`, `[...]`) evaluated with Go `path.Match`; `*` does not cross `/`. additionalProperties: true x-go-type-skip-optional-pointer: true anyOf: type: array description: >- Alternative matchers (OR). The stub matches when the blocks above pass AND at least one element here passes. Depth is exactly one — an element cannot itself contain `anyOf`. items: $ref: '#/components/schemas/StubInputAnyOfElement' x-go-type-skip-optional-pointer: true description: >- Matchers applied to the request body. All blocks present are AND-ed; an omitted or empty block always passes, so a stub with every block empty matches any request. StubInputAnyOfElement: type: object properties: ignoreArrayOrder: type: boolean default: false x-go-type-skip-optional-pointer: true description: >- Compare arrays as sets rather than ordered sequences. Applies to this matcher block only — it is not inherited by `anyOf` elements. equals: type: object additionalProperties: true x-go-type-skip-optional-pointer: true description: >- Exact match. Every listed field must be present in the request with exactly this value, case-sensitive. Arrays compare in order unless `ignoreArrayOrder` is set. contains: type: object additionalProperties: true x-go-type-skip-optional-pointer: true description: >- Subset match. The request must carry at least these fields. Strings match on substring, arrays on containment, nested objects recursively. Extra fields in the request are ignored. matches: type: object additionalProperties: true x-go-type-skip-optional-pointer: true description: >- Regex match. Each leaf value is a Go regular expression applied to the corresponding request value. glob: type: object description: >- Glob match. Each leaf value is a shell-style pattern (`*`, `?`, `[...]`) evaluated with Go `path.Match`; `*` does not cross `/`. additionalProperties: true x-go-type-skip-optional-pointer: true description: >- One alternative of an `anyOf`. Its own blocks are AND-ed together. StubHeaders: type: object x-go-type-skip-optional-pointer: true properties: equals: type: object additionalProperties: type: string x-go-type-skip-optional-pointer: true description: >- Exact match on header values (multiple values are joined with `;`). contains: type: object additionalProperties: type: string x-go-type-skip-optional-pointer: true description: >- Subset match. The request must carry at least these header names; values match on substring. matches: type: object additionalProperties: type: string x-go-type-skip-optional-pointer: true description: >- Regex match on header values. glob: type: object description: >- Glob match on header values, using Go `path.Match`. additionalProperties: type: string x-go-type-skip-optional-pointer: true anyOf: type: array description: >- Alternative header matchers (OR). The stub matches when the blocks above pass AND at least one element here passes. items: $ref: '#/components/schemas/StubHeadersAnyOfElement' x-go-type-skip-optional-pointer: true description: >- Matchers applied to gRPC request metadata. Header names are case-insensitive. All blocks present are AND-ed; an omitted or empty block always passes. StubHeadersAnyOfElement: type: object properties: equals: type: object additionalProperties: type: string x-go-type-skip-optional-pointer: true description: >- Exact match on header values (multiple values are joined with `;`). contains: type: object additionalProperties: type: string x-go-type-skip-optional-pointer: true description: >- Subset match. The request must carry at least these header names; values match on substring. matches: type: object additionalProperties: type: string x-go-type-skip-optional-pointer: true description: >- Regex match on header values. glob: type: object description: >- Glob match on header values, using Go `path.Match`. additionalProperties: type: string x-go-type-skip-optional-pointer: true description: >- One alternative of a header `anyOf`. Its own blocks are AND-ed together. StubOutput: type: object properties: data: x-go-type-skip-optional-pointer: true description: >- Response body for unary and client-streaming calls. Usually an object matching the proto message; may be a scalar when the method returns a well-known type directly. stream: type: array items: {} x-go-type-skip-optional-pointer: true description: >- Response messages for server and bidirectional streaming, sent in order. Cannot be combined with `data`, `error`, `code` or `details` on this endpoint. headers: type: object additionalProperties: type: string x-go-type-skip-optional-pointer: true description: >- Response metadata. trailers: type: object description: >- Trailing metadata, sent after the last message with the status. Independent of `headers`: the same key may appear in both, and each is delivered on its own channel. additionalProperties: type: string x-go-type-skip-optional-pointer: true error: type: string example: Message not found x-go-type-skip-optional-pointer: true description: >- gRPC status message. Returned instead of `data`, and counts as the unary side of the data/stream choice. code: type: integer format: uint32 x-go-type: codes.Code x-go-type-import: name: codes path: google.golang.org/grpc/codes example: 3 x-go-type-skip-optional-pointer: true description: >- gRPC status code; `0` (OK) is the default. details: type: array description: gRPC status details packed into google.protobuf.Any (each item must contain type URL in `type`) items: type: object required: [type] properties: type: type: string description: Full Any type URL (for example, type.googleapis.com/google.rpc.ErrorInfo) additionalProperties: true x-go-type-skip-optional-pointer: true delay: type: string x-go-type: gptypes.Duration x-go-type-import: name: gptypes path: github.com/bavix/gripmock/v3/internal/infra/types description: Delay before sending the response example: "1s" x-omitzero: true x-go-type-skip-optional-pointer: true description: >- What the stub returns. Over this API exactly one side must be set: either the unary side (`data`, `error`, `code`, `details`) or `stream`. A stub carrying both is rejected with `400`.