---
title: "Validate a stub payload without persisting"
method: POST
path: "/stubs/validate"
tags: ["stubs"]
---

# Validate a stub payload without persisting

`POST /stubs/validate`

Validates one or more stubs and returns them normalized without adding to storage

## Request body

- union
  - Stub[] — A list of stubs.
    - `id` string, uuid — Stub identifier (UUID).
    - `service` string, required — Fully qualified gRPC service name.
    - `method` string, required — gRPC method name, without the service prefix.
    - `priority` integer — 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.
    - `used` boolean — Response-only — whether the stub has matched at least once. Ignored on input.
    - `headers` StubHeaders — Matchers applied to gRPC request metadata. Header names are case-insensitive. All blocks present are AND-ed; an omitted or empty block always passes.
      - `equals` object — Exact match on header values (multiple values are joined with `;`).
      - `contains` object — Subset match. The request must carry at least these header names; values match on substring.
      - `matches` object — Regex match on header values.
      - `glob` object — Glob match on header values, using Go `path.Match`.
      - `anyOf` StubHeadersAnyOfElement[] — Alternative header matchers (OR). The stub matches when the blocks above pass AND at least one element here passes.
        - `equals` object — Exact match on header values (multiple values are joined with `;`).
        - `contains` object — Subset match. The request must carry at least these header names; values match on substring.
        - `matches` object — Regex match on header values.
        - `glob` object — Glob match on header values, using Go `path.Match`.
    - `input` StubInput, required — 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.
      - `ignoreArrayOrder` boolean — Compare arrays as sets rather than ordered sequences. Applies to this matcher block only — it is not inherited by `anyOf` elements.
      - `equals` object — 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` object — 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` object — Regex match. Each leaf value is a Go regular expression applied to the corresponding request value.
      - `glob` object — Glob match. Each leaf value is a shell-style pattern (`*`, `?`, `[...]`) evaluated with Go `path.Match`; `*` does not cross `/`.
      - `anyOf` StubInputAnyOfElement[] — 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`.
        - `ignoreArrayOrder` boolean — Compare arrays as sets rather than ordered sequences. Applies to this matcher block only — it is not inherited by `anyOf` elements.
        - `equals` object — 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` object — 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` object — Regex match. Each leaf value is a Go regular expression applied to the corresponding request value.
        - `glob` object — Glob match. Each leaf value is a shell-style pattern (`*`, `?`, `[...]`) evaluated with Go `path.Match`; `*` does not cross `/`.
    - `inputs` StubInput[] — 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`.
      - `ignoreArrayOrder` boolean — Compare arrays as sets rather than ordered sequences. Applies to this matcher block only — it is not inherited by `anyOf` elements.
      - `equals` object — 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` object — 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` object — Regex match. Each leaf value is a Go regular expression applied to the corresponding request value.
      - `glob` object — Glob match. Each leaf value is a shell-style pattern (`*`, `?`, `[...]`) evaluated with Go `path.Match`; `*` does not cross `/`.
      - `anyOf` StubInputAnyOfElement[] — 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`.
        - `ignoreArrayOrder` boolean — Compare arrays as sets rather than ordered sequences. Applies to this matcher block only — it is not inherited by `anyOf` elements.
        - `equals` object — 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` object — 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` object — Regex match. Each leaf value is a Go regular expression applied to the corresponding request value.
        - `glob` object — Glob match. Each leaf value is a shell-style pattern (`*`, `?`, `[...]`) evaluated with Go `path.Match`; `*` does not cross `/`.
    - `output` StubOutput, required — 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`.
      - `data` unknown
      - `stream` unknown[] — Response messages for server and bidirectional streaming, sent in order. Cannot be combined with `data`, `error`, `code` or `details` on this endpoint.
        - unknown
      - `headers` object — Response metadata.
      - `trailers` object — 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.
      - `error` string — gRPC status message. Returned instead of `data`, and counts as the unary side of the data/stream choice.
      - `code` integer — gRPC status code; `0` (OK) is the default.
      - `details` object[] — gRPC status details packed into google.protobuf.Any (each item must contain type URL in `type`)
        - `type` string, required — Full Any type URL (for example, type.googleapis.com/google.rpc.ErrorInfo)
      - `delay` string — Delay before sending the response
    - `options` StubOptions — Optional behavior settings for a stub
      - `times` integer — Maximum number of matches; `0` means unlimited. Once the limit is reached the stub is exhausted and stops matching, though it stays in storage.
    - `effects` StubEffect[] — Side effects applied after successful stub match
      - `action` 'upsert' | 'delete', required — `upsert` creates or replaces a stub, `delete` removes one.
      - `id` string — Target stub UUID for `delete`. May be a template that renders to a UUID.
      - `stub` object — Stub payload for `upsert`, validated after template rendering.
    - `source` string — Source of the stub (file, rest, mcp, proxy)
  - Stub — A single stub: which method it answers, which requests it accepts, and what it returns.
    - `id` string, uuid — Stub identifier (UUID).
    - `service` string, required — Fully qualified gRPC service name.
    - `method` string, required — gRPC method name, without the service prefix.
    - `priority` integer — 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.
    - `used` boolean — Response-only — whether the stub has matched at least once. Ignored on input.
    - `headers` StubHeaders — Matchers applied to gRPC request metadata. Header names are case-insensitive. All blocks present are AND-ed; an omitted or empty block always passes.
      - `equals` object — Exact match on header values (multiple values are joined with `;`).
      - `contains` object — Subset match. The request must carry at least these header names; values match on substring.
      - `matches` object — Regex match on header values.
      - `glob` object — Glob match on header values, using Go `path.Match`.
      - `anyOf` StubHeadersAnyOfElement[] — Alternative header matchers (OR). The stub matches when the blocks above pass AND at least one element here passes.
        - `equals` object — Exact match on header values (multiple values are joined with `;`).
        - `contains` object — Subset match. The request must carry at least these header names; values match on substring.
        - `matches` object — Regex match on header values.
        - `glob` object — Glob match on header values, using Go `path.Match`.
    - `input` StubInput, required — 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.
      - `ignoreArrayOrder` boolean — Compare arrays as sets rather than ordered sequences. Applies to this matcher block only — it is not inherited by `anyOf` elements.
      - `equals` object — 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` object — 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` object — Regex match. Each leaf value is a Go regular expression applied to the corresponding request value.
      - `glob` object — Glob match. Each leaf value is a shell-style pattern (`*`, `?`, `[...]`) evaluated with Go `path.Match`; `*` does not cross `/`.
      - `anyOf` StubInputAnyOfElement[] — 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`.
        - `ignoreArrayOrder` boolean — Compare arrays as sets rather than ordered sequences. Applies to this matcher block only — it is not inherited by `anyOf` elements.
        - `equals` object — 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` object — 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` object — Regex match. Each leaf value is a Go regular expression applied to the corresponding request value.
        - `glob` object — Glob match. Each leaf value is a shell-style pattern (`*`, `?`, `[...]`) evaluated with Go `path.Match`; `*` does not cross `/`.
    - `inputs` StubInput[] — 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`.
      - `ignoreArrayOrder` boolean — Compare arrays as sets rather than ordered sequences. Applies to this matcher block only — it is not inherited by `anyOf` elements.
      - `equals` object — 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` object — 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` object — Regex match. Each leaf value is a Go regular expression applied to the corresponding request value.
      - `glob` object — Glob match. Each leaf value is a shell-style pattern (`*`, `?`, `[...]`) evaluated with Go `path.Match`; `*` does not cross `/`.
      - `anyOf` StubInputAnyOfElement[] — 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`.
        - `ignoreArrayOrder` boolean — Compare arrays as sets rather than ordered sequences. Applies to this matcher block only — it is not inherited by `anyOf` elements.
        - `equals` object — 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` object — 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` object — Regex match. Each leaf value is a Go regular expression applied to the corresponding request value.
        - `glob` object — Glob match. Each leaf value is a shell-style pattern (`*`, `?`, `[...]`) evaluated with Go `path.Match`; `*` does not cross `/`.
    - `output` StubOutput, required — 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`.
      - `data` unknown
      - `stream` unknown[] — Response messages for server and bidirectional streaming, sent in order. Cannot be combined with `data`, `error`, `code` or `details` on this endpoint.
        - unknown
      - `headers` object — Response metadata.
      - `trailers` object — 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.
      - `error` string — gRPC status message. Returned instead of `data`, and counts as the unary side of the data/stream choice.
      - `code` integer — gRPC status code; `0` (OK) is the default.
      - `details` object[] — gRPC status details packed into google.protobuf.Any (each item must contain type URL in `type`)
        - `type` string, required — Full Any type URL (for example, type.googleapis.com/google.rpc.ErrorInfo)
      - `delay` string — Delay before sending the response
    - `options` StubOptions — Optional behavior settings for a stub
      - `times` integer — Maximum number of matches; `0` means unlimited. Once the limit is reached the stub is exhausted and stops matching, though it stays in storage.
    - `effects` StubEffect[] — Side effects applied after successful stub match
      - `action` 'upsert' | 'delete', required — `upsert` creates or replaces a stub, `delete` removes one.
      - `id` string — Target stub UUID for `delete`. May be a template that renders to a UUID.
      - `stub` object — Stub payload for `upsert`, validated after template rendering.
    - `source` string — Source of the stub (file, rest, mcp, proxy)

## Response `200`

Successful operation

- Stub[] — A list of stubs.
  - `id` string, uuid — Stub identifier (UUID).
  - `service` string, required — Fully qualified gRPC service name.
  - `method` string, required — gRPC method name, without the service prefix.
  - `priority` integer — 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.
  - `used` boolean — Response-only — whether the stub has matched at least once. Ignored on input.
  - `headers` StubHeaders — Matchers applied to gRPC request metadata. Header names are case-insensitive. All blocks present are AND-ed; an omitted or empty block always passes.
    - `equals` object — Exact match on header values (multiple values are joined with `;`).
    - `contains` object — Subset match. The request must carry at least these header names; values match on substring.
    - `matches` object — Regex match on header values.
    - `glob` object — Glob match on header values, using Go `path.Match`.
    - `anyOf` StubHeadersAnyOfElement[] — Alternative header matchers (OR). The stub matches when the blocks above pass AND at least one element here passes.
      - `equals` object — Exact match on header values (multiple values are joined with `;`).
      - `contains` object — Subset match. The request must carry at least these header names; values match on substring.
      - `matches` object — Regex match on header values.
      - `glob` object — Glob match on header values, using Go `path.Match`.
  - `input` StubInput, required — 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.
    - `ignoreArrayOrder` boolean — Compare arrays as sets rather than ordered sequences. Applies to this matcher block only — it is not inherited by `anyOf` elements.
    - `equals` object — 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` object — 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` object — Regex match. Each leaf value is a Go regular expression applied to the corresponding request value.
    - `glob` object — Glob match. Each leaf value is a shell-style pattern (`*`, `?`, `[...]`) evaluated with Go `path.Match`; `*` does not cross `/`.
    - `anyOf` StubInputAnyOfElement[] — 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`.
      - `ignoreArrayOrder` boolean — Compare arrays as sets rather than ordered sequences. Applies to this matcher block only — it is not inherited by `anyOf` elements.
      - `equals` object — 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` object — 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` object — Regex match. Each leaf value is a Go regular expression applied to the corresponding request value.
      - `glob` object — Glob match. Each leaf value is a shell-style pattern (`*`, `?`, `[...]`) evaluated with Go `path.Match`; `*` does not cross `/`.
  - `inputs` StubInput[] — 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`.
    - `ignoreArrayOrder` boolean — Compare arrays as sets rather than ordered sequences. Applies to this matcher block only — it is not inherited by `anyOf` elements.
    - `equals` object — 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` object — 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` object — Regex match. Each leaf value is a Go regular expression applied to the corresponding request value.
    - `glob` object — Glob match. Each leaf value is a shell-style pattern (`*`, `?`, `[...]`) evaluated with Go `path.Match`; `*` does not cross `/`.
    - `anyOf` StubInputAnyOfElement[] — 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`.
      - `ignoreArrayOrder` boolean — Compare arrays as sets rather than ordered sequences. Applies to this matcher block only — it is not inherited by `anyOf` elements.
      - `equals` object — 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` object — 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` object — Regex match. Each leaf value is a Go regular expression applied to the corresponding request value.
      - `glob` object — Glob match. Each leaf value is a shell-style pattern (`*`, `?`, `[...]`) evaluated with Go `path.Match`; `*` does not cross `/`.
  - `output` StubOutput, required — 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`.
    - `data` unknown
    - `stream` unknown[] — Response messages for server and bidirectional streaming, sent in order. Cannot be combined with `data`, `error`, `code` or `details` on this endpoint.
      - unknown
    - `headers` object — Response metadata.
    - `trailers` object — 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.
    - `error` string — gRPC status message. Returned instead of `data`, and counts as the unary side of the data/stream choice.
    - `code` integer — gRPC status code; `0` (OK) is the default.
    - `details` object[] — gRPC status details packed into google.protobuf.Any (each item must contain type URL in `type`)
      - `type` string, required — Full Any type URL (for example, type.googleapis.com/google.rpc.ErrorInfo)
    - `delay` string — Delay before sending the response
  - `options` StubOptions — Optional behavior settings for a stub
    - `times` integer — Maximum number of matches; `0` means unlimited. Once the limit is reached the stub is exhausted and stops matching, though it stays in storage.
  - `effects` StubEffect[] — Side effects applied after successful stub match
    - `action` 'upsert' | 'delete', required — `upsert` creates or replaces a stub, `delete` removes one.
    - `id` string — Target stub UUID for `delete`. May be a template that renders to a UUID.
    - `stub` object — Stub payload for `upsert`, validated after template rendering.
  - `source` string — Source of the stub (file, rest, mcp, proxy)

## Other responses

- `400` — 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` — Internal Server Error

---

[API](https://skmtc.net/bavix/apis/gripmock-api-schema.md) · [All operations](https://skmtc.net/bavix/apis/gripmock-api-schema/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/bavix/gripmock-api-schema/revisions/38f761f66622/schema)
