EchoRelay
Was dieses MCP kann
Manages a hosted API relay runtime, including projects, endpoints, credentials, publishing, keys, delivery logs, and dead-letter queues.
Tools
Eingabeschema
{'type': 'object', 'required': ['lineKey'], 'properties': {'lineKey': {'type': 'string', 'description': 'The line key, e.g. "v1".'}, 'commitMode': {'enum': ['draft', 'publish'], 'type': 'string', 'description': 'Defaults to publish. Draft writes require draftRevision.'}, 'draftRevision': {'type': 'integer', 'description': 'Current line draft revision, required for draft writes.'}}}
Eingabeschema
{'type': 'object', 'required': ['slug'], 'properties': {'slug': {'type': 'string', 'description': 'The slug of a project you own.'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey', 'draftRevision'], 'properties': {'lineKey': {'type': 'string'}, 'draftRevision': {'type': 'integer'}}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'required': ['plan'], 'properties': {'plan': {'enum': ['free', 'pro', 'scale'], 'type': 'string'}}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'required': ['name', 'mode'], 'properties': {'mode': {'enum': ['live', 'test'], 'type': 'string', 'description': "live → paid pool, test → testing pool (rate-limited to the plan's live rate)."}, 'name': {'type': 'string', 'description': 'Human-readable label, up to 120 characters.'}, 'ttlDays': {'type': ['integer', 'null'], 'description': "Lifetime in days. Omit to use the project's defaultKeyTtlDays from get_key_policy. Null = never expires (owner-only unless editorsMayCreateNonExpiringKeys is set)."}}}
Eingabeschema
{'type': 'object', 'required': ['name', 'destinationHost', 'auth'], 'properties': {'auth': {'type': 'object', 'required': ['type'], 'properties': {'key': {'type': 'string', 'description': 'apiKeyHeader / apiKeyQuery / publicPrivateKey.'}, 'type': {'enum': ['none', 'bearer', 'basic', 'apiKeyHeader', 'apiKeyQuery', 'publicPrivateKey'], 'type': 'string'}, 'token': {'type': 'string', 'description': 'bearer only.'}, 'secret': {'type': 'string', 'description': 'publicPrivateKey only.'}, 'password': {'type': 'string', 'description': 'basic only.'}, 'username': {'type': 'string', 'description': 'basic only.'}, 'paramName': {'type': 'string', 'description': 'apiKeyQuery only, e.g. "api_key".'}, 'headerName': {'type': 'string', 'description': 'apiKeyHeader only, e.g. "X-Api-Key".'}}, 'description': "The credential's auth shape."}, 'name': {'type': 'string', 'description': 'Human-readable label, up to 120 characters.'}, 'destinationHost': {'type': 'string', 'description': 'The only host this credential may be sent to, e.g. "api.stripe.com", or a single-label wildcard, e.g. "*.stripe.com" (matches api.stripe.com, not stripe.com and not a.b.stripe.com). Host only — no scheme, port or path. Internationalised hosts must be given in punycode ("xn--…"). Permanent: attaching this credential to a target on any other host is refused, and it cannot be changed later — a different destination means a new credential, which means entering the secret again.'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey', 'endpoint'], 'properties': {'lineKey': {'type': 'string', 'description': 'The line key to create the endpoint under.'}, 'endpoint': {'type': 'object', 'properties': {'url': {'type': 'string', 'pattern': '^/[A-Za-z0-9/_\\-{}]*$', 'description': 'Path under the line, e.g. "/webhook". Must start with "/" and contain only [A-Za-z0-9/_-{}].'}, 'mock': {'type': 'boolean', 'description': 'When true, callers receive mockResponse without fan-out to targets. Targets are saved but not invoked.'}, 'name': {'type': 'string', 'minLength': 1, 'description': 'Human-readable label for the endpoint.'}, 'strict': {'type': 'boolean', 'description': 'When true, validation rejects any attribute not declared in attributes[]. Default false.'}, 'targets': {'type': 'array', 'items': {'type': 'object', 'required': ['name', 'targetUrl', 'auth', 'deliveryMode'], 'properties': {'id': {'type': 'string', 'description': 'Returned on reads. Send it back unchanged to update that target and keep its stored secrets. Targets are matched by id; without one, by the same name and targetUrl; without either, a patch to the target in the same position keeps its secrets, as long as the list keeps its length, the patch does not change both its name and targetUrl, and a changed targetUrl stays on the same host. Any other target is new and must carry its own secrets.'}, 'auth': {'type': 'object', 'required': ['type'], 'properties': {'key': {'type': 'string', 'description': 'Required when type=apiKeyHeader or type=apiKeyQuery or type=publicPrivateKey.'}, 'type': {'enum': ['none', 'bearer', 'basic', 'apiKeyHeader', 'apiKeyQuery', 'publicPrivateKey'], 'type': 'string'}, 'token': {'type': 'string', 'description': 'Required when type=bearer.'}, 'secret': {'type': 'string', 'description': 'Required when type=publicPrivateKey.'}, 'password': {'type': 'string', 'description': 'Required when type=basic.'}, 'username': {'type': 'string', 'description': 'Required when type=basic.'}, 'paramName': {'type': 'string', 'description': 'Required when type=apiKeyQuery.'}, 'headerName': {'type': 'string', 'description': 'Required when type=apiKeyHeader.'}}, 'description': 'Outbound auth applied to the request. On reads, secrets are redacted to "***" — round-trip the sentinel to keep the stored secret. Ignored when credentialVaultEntryId is set.', 'additionalProperties': False}, 'name': {'type': 'string', 'description': 'Display name for the target.'}, 'mapping': {'type': 'array', 'items': {'type': 'object', 'required': ['sourceIn', 'sourceName', 'targetIn', 'targetName'], 'properties': {'sourceIn': {'enum': ['body', 'query', 'header', 'path'], 'type': 'string'}, 'targetIn': {'enum': ['body', 'query', 'header'], 'type': 'string'}, 'template': {'type': 'string', 'description': 'Optional templated value (e.g. "Bearer {value}").'}, 'sourceName': {'type': 'string', 'description': 'Inbound field name to read.'}, 'targetName': {'type': 'string', 'description': 'Outbound field name to write.'}}, 'additionalProperties': False}, 'description': 'Optional transformer rules. Each rule moves or renames a field from the inbound request to the outbound one.'}, 'targetUrl': {'type': 'string', 'format': 'uri', 'description': 'Outbound URL. Cannot point back to this project (the Framework rejects relay loops).'}, 'callbackURL': {'type': 'string', 'format': 'uri', 'description': "Pushed once this target's delivery reaches a terminal status — see get_receipts' callbackState. Must be https. Meaningful for async targets only — refused on sync/stream. Cannot point back into this project (the same relay-loop rule as targetUrl) and must be inside the project's outbound host allowlist when one is set. Unset = the customer polls the receipt instead."}, 'retryPolicy': {'type': ['object', 'null'], 'properties': {'retryOn': {'type': 'array', 'items': {'type': 'integer', 'maximum': 599, 'minimum': 100}, 'description': 'HTTP status codes that trigger a retry. Default [429, 500, 502, 503, 504].'}, 'maxAttempts': {'type': 'integer', 'maximum': 14, 'minimum': 1, 'description': 'Total delivery attempts, counting the first. 1 fails fast: one try, then the dead-letter queue. Higher values keep retrying with a widening gap between tries — at the default backoffMultiplier, roughly under a minute at 4, a few minutes at 7, about an hour at 10, a few hours at 14. Anything still undelivered lands in the dead-letter queue. Defaults to 14.'}, 'backoffMultiplier': {'type': 'number', 'maximum': 5, 'minimum': 1, 'description': 'How sharply the gap between tries widens. Higher spends the same attempts over a longer stretch. Defaults to 2.0.'}}, 'description': 'Async retry policy. Ignored unless deliveryMode=async. Leave it unset (null) and the platform default applies, which behaves the same as maxAttempts at its maximum. get_endpoint reports which is in effect: this object when set, null when the platform default applies.', 'additionalProperties': False}, 'syncTimeout': {'type': 'integer', 'maximum': 90, 'minimum': 1, 'description': 'Seconds the caller waits for a sync target. Ignored unless deliveryMode=sync.'}, 'deliveryMode': {'enum': ['async', 'sync', 'stream'], 'type': 'string', 'description': 'async = queued + retried (default); sync = caller waits up to syncTimeout for the target response; stream = SSE pass-through (max 1 per endpoint).'}, 'transformers': {'type': 'array', 'items': {'type': 'object', 'required': ['type'], 'properties': {'type': {'enum': ['mergeFields', 'renameField', 'removeField', 'addField', 'mapValue', 'binaryToUrl'], 'type': 'string', 'description': 'mergeFields: from+to(+separator). renameField: from+to. removeField: field. addField: to+value. mapValue: field+mapping. binaryToUrl: ttlSeconds?+maxSizeMB? (both clamped server-side — omit for the server default).'}, 'params': {'type': ['object', 'null'], 'properties': {'to': {'type': 'string', 'description': 'Destination field — mergeFields / renameField / addField.'}, 'from': {'type': 'array', 'items': {'type': 'string'}, 'description': 'mergeFields (all sources) / renameField (first element is the source).'}, 'field': {'type': 'string', 'description': 'Target field — removeField / mapValue.'}, 'value': {'type': 'string', 'description': 'Constant value to set — addField.'}, 'mapping': {'type': 'object', 'description': 'Value lookup table — mapValue.', 'additionalProperties': {'type': 'string'}}, 'maxSizeMB': {'type': 'integer', 'minimum': 1, 'description': 'Max upload size in MB — binaryToUrl.'}, 'separator': {'type': 'string', 'description': 'Join separator — mergeFields (default " ").'}, 'ttlSeconds': {'type': 'integer', 'minimum': 1, 'description': 'Temp file lifetime in seconds — binaryToUrl.'}}, 'description': 'Only the keys the chosen type reads are accepted; see the type description above.', 'additionalProperties': False}}, 'additionalProperties': False}, 'description': 'Request transformation pipeline applied to this target before delivery. Empty array = no transformation.'}, 'answerMapping': {'type': ['object', 'null'], 'description': "Reshapes this target's answer into what the caller receives — a tree of typed nodes conforming to the same published grammar as outgoingMapping. Refused on a stream target (deliveryMode=stream) — a stream's response is proxied straight through and never reshaped. null = no reshaping, the answer reaches the caller verbatim; paths, types and cycles are checked server-side."}, 'signingSecret': {'type': ['string', 'null'], 'description': 'Signs the body delivered to this target — separate from auth above, which authenticates OUTBOUND to the target. Shape: "whsec_" followed by base64 of 32 random bytes. Omit to leave unchanged; set to null to disable signing; set to your own whsec_-shaped value to use it verbatim (rejected otherwise, including an empty string — you hold this secret, so only you can supply it). On reads, a configured secret is redacted to "***" — round-trip that sentinel to keep the stored secret.'}, 'answerVariants': {'type': ['object', 'null'], 'description': 'The conditional form of answerMapping, for a target whose answers do not all share one shape: one mapping per reply instead of one for every reply. Requires "distinguishBy" naming the single thing that tells them apart ({"source":"status"}, {"source":"header","name":…} or {"source":"bodyField","path":…}), "variants" as an object keyed by the value it matches — an exact status like "429", a class like "4XX", or "default" — each holding a tree in the same grammar as answerMapping — or, where the caller should be answered with a status of your own, an object {"mapping": <tree>, "replyStatus": 402} — and "onNoMatch", which has no default and must be either "passthrough" (hand the vendor\'s answer back untouched) or "fail" (answer 422 naming the value that matched nothing). A replyStatus is what the caller sees and never what the delivery is measured or charged as; it must be a status that can carry a body (200–599, excluding 204, 205 and redirects), and setting one drops the vendor\'s own response headers, which describe the answer it replaced. A variant keyed on a status that carries no body (204, 205, 304) is reachable only when it sets one. Mutually exclusive with answerMapping on this target, and refused on a stream target for the same reason answerMapping is. A variant whose tree does not compile is refused when the line is published, not silently dropped. null = no reshaping.'}, 'outgoingMapping': {'type': ['object', 'null'], 'description': 'Reshapes the request into what this target expects — a tree of typed nodes conforming to the published grammar at "https://schemas.echorelay.dev/transform/mapping/v1.json" (its own $schema key must name that value). Mutually exclusive with mapping and transformers on this target, and with the endpoint\'s own transformers — the write is rejected if both are set. null = no reshaping (today\'s behaviour, and the only value this schema itself can validate; paths, types and cycles are checked server-side).'}, 'credentialVaultEntryId': {'type': 'string', 'description': "References a saved credential (see list_credentials/create_credential) instead of inline auth — the auth field above is ignored when this is set. Must belong to the same project. The credential is bound to a destination when it is created: targetUrl must be https and its host must match that credential's destinationHost, or the write is rejected."}}, 'additionalProperties': False}, 'description': 'Outbound destinations. Required unless mock=true. Each entry becomes one queue fan-out.'}, 'rateLimit': {'type': ['object', 'null'], 'required': ['requests', 'windowSeconds'], 'properties': {'requests': {'type': 'integer', 'minimum': 1, 'description': 'Requests allowed per window.'}, 'windowSeconds': {'type': 'integer', 'minimum': 1, 'description': 'Window size in seconds.'}}, 'description': 'Per-endpoint rate limit. Set to null to remove. Both fields required together.', 'additionalProperties': False}, 'allowedIPs': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Inbound IP allowlist, in CIDR notation (e.g. "203.0.113.0/24", "::1/128"). Empty array = allow all.'}, 'attributes': {'type': 'array', 'items': {'type': 'object', 'required': ['name', 'in', 'attributeType'], 'properties': {'id': {'type': 'string', 'format': 'uuid', 'description': 'Stable attribute id. Optional on create; generated when omitted.'}, 'in': {'enum': ['body', 'query', 'header', 'path'], 'type': 'string', 'description': 'Where the attribute is read from on the inbound request.'}, 'name': {'type': 'string', 'description': 'Attribute field name (matches the inbound payload key).'}, 'params': {'type': 'object', 'description': 'Validator parameters. Recognised keys: min, max (range/stringLength/arrayLength), values (oneOf/arraySubset/arrayIntersect), numbers (numberOneOf), type (typeValidator/arrayType).', 'additionalProperties': True}, 'schema': {'type': ['object', 'null'], 'required': ['type'], 'properties': {'type': {'enum': ['string', 'int', 'double', 'bool', 'array', 'object'], 'type': 'string'}, 'items': {'type': 'object', 'description': 'For type=array: the element schema (same form).'}, 'maxItems': {'type': 'integer', 'minimum': 0}, 'minItems': {'type': 'integer', 'minimum': 0}, 'required': {'type': 'array', 'items': {'type': 'string'}, 'description': 'For type=object: property names that must be present.'}, 'properties': {'type': 'object', 'description': 'For type=object: map of property name → schema (same form).'}, 'additionalProperties': {'type': 'boolean', 'description': 'For type=object: when false, reject members not in properties.'}}, 'description': 'Optional precise JSON shape, enforced recursively alongside validators[]. scalar: {type}. array: {type:"array", items:<schema>, minItems?, maxItems?}. object: {type:"object", properties:{name:<schema>}, required?:[...], additionalProperties?:bool}. type must match attributeType.', 'additionalProperties': True}, 'logging': {'enum': ['loggable', 'obscured', 'nonLoggable'], 'type': 'string', 'description': 'How the value appears in the request log. obscured = masked; nonLoggable = stripped entirely.'}, 'required': {'type': 'boolean', 'description': 'When true, requests missing this attribute are rejected.'}, 'forwarding': {'enum': ['blocked', 'forwardInPlace'], 'type': 'string', 'description': 'Only meaningful for in=query or in=path. blocked (default): validated, never sent to the target. forwardInPlace: sent to the target in the same location — a query attribute as a query parameter, a path attribute as a path segment. A path attribute forwards only when its name is its own zero-based segment position ("0" for the first segment after the endpoint URL, "1" for the next, …) — path segments are matched positionally, not by name. To carry a value into the body or a header instead, leave this blocked and add a field mapping on the target sourced from this attribute.'}, 'validators': {'type': 'array', 'items': {'enum': ['email', 'phone', 'int', 'double', 'bool', 'string', 'array', 'dictionary', 'range', 'oneOf', 'type', 'nil', 'not', 'empty', 'arrayType', 'arrayLength', 'arraySubset', 'arrayIntersect', 'intString', 'doubleString', 'boolString', 'numberString', 'numberOneOf', 'stringLength', 'stringEmpty', 'stringJson', 'dictionaryString'], 'type': 'string'}, 'description': 'Validator names to run, in order. See params for any bounds/values they need.'}, 'description': {'type': 'string', 'description': 'Shown in the auto-generated OpenAPI doc.'}, 'defaultValue': {'description': 'Used when the attribute is absent and required=false. Any scalar.'}, 'attributeType': {'enum': ['string', 'int', 'double', 'bool', 'array', 'object'], 'type': 'string', 'description': 'Expected value type.'}}, 'additionalProperties': False}, 'description': 'Request validators. One entry per attribute; the Framework rejects callers whose payload fails the configured rules. Empty array = no validation.'}, 'httpMethod': {'enum': ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'], 'type': 'string', 'description': 'HTTP method callers must use. GET endpoints cannot declare a body attribute (see attributes[].in).'}, 'mockResponse': {'type': ['object', 'null'], 'properties': {'body': {'type': 'string', 'description': 'Literal response body.'}, 'statusCode': {'type': 'integer', 'maximum': 599, 'minimum': 100}, 'contentType': {'type': 'string', 'description': 'e.g. "application/json".'}}, 'description': 'Response returned in mock mode. Required when mock=true.', 'additionalProperties': False}, 'transformers': {'type': ['array', 'null'], 'items': {'type': 'object', 'required': ['type'], 'properties': {'type': {'enum': ['mergeFields', 'renameField', 'removeField', 'addField', 'mapValue', 'binaryToUrl'], 'type': 'string', 'description': 'mergeFields: from+to(+separator). renameField: from+to. removeField: field. addField: to+value. mapValue: field+mapping. binaryToUrl: ttlSeconds?+maxSizeMB? (both clamped server-side — omit for the server default).'}, 'params': {'type': ['object', 'null'], 'properties': {'to': {'type': 'string', 'description': 'Destination field — mergeFields / renameField / addField.'}, 'from': {'type': 'array', 'items': {'type': 'string'}, 'description': 'mergeFields (all sources) / renameField (first element is the source).'}, 'field': {'type': 'string', 'description': 'Target field — removeField / mapValue.'}, 'value': {'type': 'string', 'description': 'Constant value to set — addField.'}, 'mapping': {'type': 'object', 'description': 'Value lookup table — mapValue.', 'additionalProperties': {'type': 'string'}}, 'maxSizeMB': {'type': 'integer', 'minimum': 1, 'description': 'Max upload size in MB — binaryToUrl.'}, 'separator': {'type': 'string', 'description': 'Join separator — mergeFields (default " ").'}, 'ttlSeconds': {'type': 'integer', 'minimum': 1, 'description': 'Temp file lifetime in seconds — binaryToUrl.'}}, 'description': 'Only the keys the chosen type reads are accepted; see the type description above.', 'additionalProperties': False}}, 'additionalProperties': False}, 'description': 'Endpoint-level request transformation pipeline, applied before any target-level transformers. Set to null to remove the override and inherit the line default (if the line has one); set to an empty array to explicitly apply no transformation even when the line has a default. Omit on update_endpoint to leave the existing value unchanged.'}, 'idempotencyEnabled': {'type': 'boolean', 'description': "When true, the Framework deduplicates on the caller's Idempotency-Key header. Default true."}}, 'description': 'An EchoRelay endpoint. Round-trips with the JSON returned by get_endpoint.', 'additionalProperties': False}, 'commitMode': {'enum': ['draft', 'publish'], 'type': 'string', 'description': 'Defaults to publish. Draft writes require draftRevision.'}, 'scheduledAt': {'type': 'string', 'description': 'Compatibility alias: stage this endpoint in its line draft then schedule that line.'}, 'draftRevision': {'type': 'integer', 'description': 'Current line draft revision, required for draft writes.'}}}
Eingabeschema
{'type': 'object', 'required': ['name', 'lineKey'], 'properties': {'name': {'type': 'string', 'description': 'Human-readable line name.'}, 'lineKey': {'type': 'string', 'description': 'URL key, lowercase letters/digits/hyphens, e.g. "v1".'}, 'commitMode': {'enum': ['draft', 'publish'], 'type': 'string', 'description': 'Defaults to publish. Draft writes require draftRevision.'}, 'draftRevision': {'type': 'integer', 'description': 'Current line draft revision, required for draft writes.'}}}
Eingabeschema
{'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'Human-readable project name (1–100 chars). The slug is derived from it.'}}}
Eingabeschema
{'type': 'object', 'required': ['slug', 'label'], 'properties': {'slug': {'type': 'string', 'description': 'The slug of a project you own.'}, 'label': {'type': 'string', 'description': 'Human-readable management token label (1–100 chars).'}, 'scopes': {'type': 'array', 'items': {'enum': ['read', 'config', 'mint:keys', 'manage:billing'], 'type': 'string'}, 'description': "Scopes for the minted management token: must be a subset of this management token's own scopes. `read` is always granted. `spend` and the legacy `billing` scope are never mintable here (panel-only). Default: read + config."}, 'expiresInDays': {'type': 'integer', 'maximum': 90, 'minimum': 1, 'description': 'Days until the minted management token expires. Default 30. API-minted management tokens always expire.'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey'], 'properties': {'lineKey': {'type': 'string', 'description': 'The line key, e.g. "v1".'}, 'commitMode': {'enum': ['draft', 'publish'], 'type': 'string', 'description': 'Defaults to publish. Draft writes require draftRevision.'}, 'draftRevision': {'type': 'integer', 'description': 'Current line draft revision, required for draft writes.'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey'], 'properties': {'lineKey': {'type': 'string', 'description': 'The line key, e.g. "v1".'}}}
Eingabeschema
{'type': 'object', 'required': ['credentialId'], 'properties': {'credentialId': {'type': 'string', 'description': 'UUID of the credential to delete.'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey', 'endpointId'], 'properties': {'lineKey': {'type': 'string', 'description': 'The line key, e.g. "v1".'}, 'commitMode': {'enum': ['draft', 'publish'], 'type': 'string', 'description': 'Defaults to publish. Draft writes require draftRevision.'}, 'endpointId': {'type': 'string', 'description': 'The endpoint UUID.'}, 'draftRevision': {'type': 'integer', 'description': 'Current line draft revision, required for draft writes.'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey'], 'properties': {'lineKey': {'type': 'string', 'description': 'The line key, e.g. "v1".'}, 'commitMode': {'enum': ['draft', 'publish'], 'type': 'string', 'description': 'Defaults to publish. Draft writes require draftRevision.'}, 'draftRevision': {'type': 'integer', 'description': 'Current line draft revision, required for draft writes.'}}}
Eingabeschema
{'type': 'object', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'Dead-letter entry id from list_dlq.'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey', 'endpointId', 'draftRevision'], 'properties': {'lineKey': {'type': 'string'}, 'endpointId': {'type': 'string'}, 'draftRevision': {'type': 'integer'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey', 'draftRevision'], 'properties': {'lineKey': {'type': 'string'}, 'draftRevision': {'type': 'integer'}}}
Eingabeschema
{'type': 'object', 'required': ['addonKey', 'targetAddonKey'], 'properties': {'addonKey': {'type': 'string', 'description': 'Current active add-on key to downgrade from.'}, 'targetAddonKey': {'type': 'string', 'description': 'Target (lower) add-on key to downgrade to.'}}, 'additionalProperties': False}
Eingabeschema
{'type': 'object', 'required': ['lineKey', 'endpoint'], 'properties': {'sample': {'type': ['object', 'array', 'string', 'number', 'boolean', 'null'], 'description': 'Optional: a request payload, shaped as one a caller would actually send, passed as JSON rather than as a string containing JSON. Every target carrying an outgoingMapping is evaluated against it and the verdict is attached to that target as outgoingMappingEvaluation.'}, 'lineKey': {'type': 'string', 'description': 'The line key.'}, 'endpoint': {'type': 'object', 'properties': {'url': {'type': 'string', 'pattern': '^/[A-Za-z0-9/_\\-{}]*$', 'description': 'Path under the line, e.g. "/webhook". Must start with "/" and contain only [A-Za-z0-9/_-{}].'}, 'mock': {'type': 'boolean', 'description': 'When true, callers receive mockResponse without fan-out to targets. Targets are saved but not invoked.'}, 'name': {'type': 'string', 'minLength': 1, 'description': 'Human-readable label for the endpoint.'}, 'strict': {'type': 'boolean', 'description': 'When true, validation rejects any attribute not declared in attributes[]. Default false.'}, 'targets': {'type': 'array', 'items': {'type': 'object', 'required': ['name', 'targetUrl', 'auth', 'deliveryMode'], 'properties': {'id': {'type': 'string', 'description': 'Returned on reads. Send it back unchanged to update that target and keep its stored secrets. Targets are matched by id; without one, by the same name and targetUrl; without either, a patch to the target in the same position keeps its secrets, as long as the list keeps its length, the patch does not change both its name and targetUrl, and a changed targetUrl stays on the same host. Any other target is new and must carry its own secrets.'}, 'auth': {'type': 'object', 'required': ['type'], 'properties': {'key': {'type': 'string', 'description': 'Required when type=apiKeyHeader or type=apiKeyQuery or type=publicPrivateKey.'}, 'type': {'enum': ['none', 'bearer', 'basic', 'apiKeyHeader', 'apiKeyQuery', 'publicPrivateKey'], 'type': 'string'}, 'token': {'type': 'string', 'description': 'Required when type=bearer.'}, 'secret': {'type': 'string', 'description': 'Required when type=publicPrivateKey.'}, 'password': {'type': 'string', 'description': 'Required when type=basic.'}, 'username': {'type': 'string', 'description': 'Required when type=basic.'}, 'paramName': {'type': 'string', 'description': 'Required when type=apiKeyQuery.'}, 'headerName': {'type': 'string', 'description': 'Required when type=apiKeyHeader.'}}, 'description': 'Outbound auth applied to the request. On reads, secrets are redacted to "***" — round-trip the sentinel to keep the stored secret. Ignored when credentialVaultEntryId is set.', 'additionalProperties': False}, 'name': {'type': 'string', 'description': 'Display name for the target.'}, 'mapping': {'type': 'array', 'items': {'type': 'object', 'required': ['sourceIn', 'sourceName', 'targetIn', 'targetName'], 'properties': {'sourceIn': {'enum': ['body', 'query', 'header', 'path'], 'type': 'string'}, 'targetIn': {'enum': ['body', 'query', 'header'], 'type': 'string'}, 'template': {'type': 'string', 'description': 'Optional templated value (e.g. "Bearer {value}").'}, 'sourceName': {'type': 'string', 'description': 'Inbound field name to read.'}, 'targetName': {'type': 'string', 'description': 'Outbound field name to write.'}}, 'additionalProperties': False}, 'description': 'Optional transformer rules. Each rule moves or renames a field from the inbound request to the outbound one.'}, 'targetUrl': {'type': 'string', 'format': 'uri', 'description': 'Outbound URL. Cannot point back to this project (the Framework rejects relay loops).'}, 'callbackURL': {'type': 'string', 'format': 'uri', 'description': "Pushed once this target's delivery reaches a terminal status — see get_receipts' callbackState. Must be https. Meaningful for async targets only — refused on sync/stream. Cannot point back into this project (the same relay-loop rule as targetUrl) and must be inside the project's outbound host allowlist when one is set. Unset = the customer polls the receipt instead."}, 'retryPolicy': {'type': ['object', 'null'], 'properties': {'retryOn': {'type': 'array', 'items': {'type': 'integer', 'maximum': 599, 'minimum': 100}, 'description': 'HTTP status codes that trigger a retry. Default [429, 500, 502, 503, 504].'}, 'maxAttempts': {'type': 'integer', 'maximum': 14, 'minimum': 1, 'description': 'Total delivery attempts, counting the first. 1 fails fast: one try, then the dead-letter queue. Higher values keep retrying with a widening gap between tries — at the default backoffMultiplier, roughly under a minute at 4, a few minutes at 7, about an hour at 10, a few hours at 14. Anything still undelivered lands in the dead-letter queue. Defaults to 14.'}, 'backoffMultiplier': {'type': 'number', 'maximum': 5, 'minimum': 1, 'description': 'How sharply the gap between tries widens. Higher spends the same attempts over a longer stretch. Defaults to 2.0.'}}, 'description': 'Async retry policy. Ignored unless deliveryMode=async. Leave it unset (null) and the platform default applies, which behaves the same as maxAttempts at its maximum. get_endpoint reports which is in effect: this object when set, null when the platform default applies.', 'additionalProperties': False}, 'syncTimeout': {'type': 'integer', 'maximum': 90, 'minimum': 1, 'description': 'Seconds the caller waits for a sync target. Ignored unless deliveryMode=sync.'}, 'deliveryMode': {'enum': ['async', 'sync', 'stream'], 'type': 'string', 'description': 'async = queued + retried (default); sync = caller waits up to syncTimeout for the target response; stream = SSE pass-through (max 1 per endpoint).'}, 'transformers': {'type': 'array', 'items': {'type': 'object', 'required': ['type'], 'properties': {'type': {'enum': ['mergeFields', 'renameField', 'removeField', 'addField', 'mapValue', 'binaryToUrl'], 'type': 'string', 'description': 'mergeFields: from+to(+separator). renameField: from+to. removeField: field. addField: to+value. mapValue: field+mapping. binaryToUrl: ttlSeconds?+maxSizeMB? (both clamped server-side — omit for the server default).'}, 'params': {'type': ['object', 'null'], 'properties': {'to': {'type': 'string', 'description': 'Destination field — mergeFields / renameField / addField.'}, 'from': {'type': 'array', 'items': {'type': 'string'}, 'description': 'mergeFields (all sources) / renameField (first element is the source).'}, 'field': {'type': 'string', 'description': 'Target field — removeField / mapValue.'}, 'value': {'type': 'string', 'description': 'Constant value to set — addField.'}, 'mapping': {'type': 'object', 'description': 'Value lookup table — mapValue.', 'additionalProperties': {'type': 'string'}}, 'maxSizeMB': {'type': 'integer', 'minimum': 1, 'description': 'Max upload size in MB — binaryToUrl.'}, 'separator': {'type': 'string', 'description': 'Join separator — mergeFields (default " ").'}, 'ttlSeconds': {'type': 'integer', 'minimum': 1, 'description': 'Temp file lifetime in seconds — binaryToUrl.'}}, 'description': 'Only the keys the chosen type reads are accepted; see the type description above.', 'additionalProperties': False}}, 'additionalProperties': False}, 'description': 'Request transformation pipeline applied to this target before delivery. Empty array = no transformation.'}, 'answerMapping': {'type': ['object', 'null'], 'description': "Reshapes this target's answer into what the caller receives — a tree of typed nodes conforming to the same published grammar as outgoingMapping. Refused on a stream target (deliveryMode=stream) — a stream's response is proxied straight through and never reshaped. null = no reshaping, the answer reaches the caller verbatim; paths, types and cycles are checked server-side."}, 'signingSecret': {'type': ['string', 'null'], 'description': 'Signs the body delivered to this target — separate from auth above, which authenticates OUTBOUND to the target. Shape: "whsec_" followed by base64 of 32 random bytes. Omit to leave unchanged; set to null to disable signing; set to your own whsec_-shaped value to use it verbatim (rejected otherwise, including an empty string — you hold this secret, so only you can supply it). On reads, a configured secret is redacted to "***" — round-trip that sentinel to keep the stored secret.'}, 'answerVariants': {'type': ['object', 'null'], 'description': 'The conditional form of answerMapping, for a target whose answers do not all share one shape: one mapping per reply instead of one for every reply. Requires "distinguishBy" naming the single thing that tells them apart ({"source":"status"}, {"source":"header","name":…} or {"source":"bodyField","path":…}), "variants" as an object keyed by the value it matches — an exact status like "429", a class like "4XX", or "default" — each holding a tree in the same grammar as answerMapping — or, where the caller should be answered with a status of your own, an object {"mapping": <tree>, "replyStatus": 402} — and "onNoMatch", which has no default and must be either "passthrough" (hand the vendor\'s answer back untouched) or "fail" (answer 422 naming the value that matched nothing). A replyStatus is what the caller sees and never what the delivery is measured or charged as; it must be a status that can carry a body (200–599, excluding 204, 205 and redirects), and setting one drops the vendor\'s own response headers, which describe the answer it replaced. A variant keyed on a status that carries no body (204, 205, 304) is reachable only when it sets one. Mutually exclusive with answerMapping on this target, and refused on a stream target for the same reason answerMapping is. A variant whose tree does not compile is refused when the line is published, not silently dropped. null = no reshaping.'}, 'outgoingMapping': {'type': ['object', 'null'], 'description': 'Reshapes the request into what this target expects — a tree of typed nodes conforming to the published grammar at "https://schemas.echorelay.dev/transform/mapping/v1.json" (its own $schema key must name that value). Mutually exclusive with mapping and transformers on this target, and with the endpoint\'s own transformers — the write is rejected if both are set. null = no reshaping (today\'s behaviour, and the only value this schema itself can validate; paths, types and cycles are checked server-side).'}, 'credentialVaultEntryId': {'type': 'string', 'description': "References a saved credential (see list_credentials/create_credential) instead of inline auth — the auth field above is ignored when this is set. Must belong to the same project. The credential is bound to a destination when it is created: targetUrl must be https and its host must match that credential's destinationHost, or the write is rejected."}}, 'additionalProperties': False}, 'description': 'Outbound destinations. Required unless mock=true. Each entry becomes one queue fan-out.'}, 'rateLimit': {'type': ['object', 'null'], 'required': ['requests', 'windowSeconds'], 'properties': {'requests': {'type': 'integer', 'minimum': 1, 'description': 'Requests allowed per window.'}, 'windowSeconds': {'type': 'integer', 'minimum': 1, 'description': 'Window size in seconds.'}}, 'description': 'Per-endpoint rate limit. Set to null to remove. Both fields required together.', 'additionalProperties': False}, 'allowedIPs': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Inbound IP allowlist, in CIDR notation (e.g. "203.0.113.0/24", "::1/128"). Empty array = allow all.'}, 'attributes': {'type': 'array', 'items': {'type': 'object', 'required': ['name', 'in', 'attributeType'], 'properties': {'id': {'type': 'string', 'format': 'uuid', 'description': 'Stable attribute id. Optional on create; generated when omitted.'}, 'in': {'enum': ['body', 'query', 'header', 'path'], 'type': 'string', 'description': 'Where the attribute is read from on the inbound request.'}, 'name': {'type': 'string', 'description': 'Attribute field name (matches the inbound payload key).'}, 'params': {'type': 'object', 'description': 'Validator parameters. Recognised keys: min, max (range/stringLength/arrayLength), values (oneOf/arraySubset/arrayIntersect), numbers (numberOneOf), type (typeValidator/arrayType).', 'additionalProperties': True}, 'schema': {'type': ['object', 'null'], 'required': ['type'], 'properties': {'type': {'enum': ['string', 'int', 'double', 'bool', 'array', 'object'], 'type': 'string'}, 'items': {'type': 'object', 'description': 'For type=array: the element schema (same form).'}, 'maxItems': {'type': 'integer', 'minimum': 0}, 'minItems': {'type': 'integer', 'minimum': 0}, 'required': {'type': 'array', 'items': {'type': 'string'}, 'description': 'For type=object: property names that must be present.'}, 'properties': {'type': 'object', 'description': 'For type=object: map of property name → schema (same form).'}, 'additionalProperties': {'type': 'boolean', 'description': 'For type=object: when false, reject members not in properties.'}}, 'description': 'Optional precise JSON shape, enforced recursively alongside validators[]. scalar: {type}. array: {type:"array", items:<schema>, minItems?, maxItems?}. object: {type:"object", properties:{name:<schema>}, required?:[...], additionalProperties?:bool}. type must match attributeType.', 'additionalProperties': True}, 'logging': {'enum': ['loggable', 'obscured', 'nonLoggable'], 'type': 'string', 'description': 'How the value appears in the request log. obscured = masked; nonLoggable = stripped entirely.'}, 'required': {'type': 'boolean', 'description': 'When true, requests missing this attribute are rejected.'}, 'forwarding': {'enum': ['blocked', 'forwardInPlace'], 'type': 'string', 'description': 'Only meaningful for in=query or in=path. blocked (default): validated, never sent to the target. forwardInPlace: sent to the target in the same location — a query attribute as a query parameter, a path attribute as a path segment. A path attribute forwards only when its name is its own zero-based segment position ("0" for the first segment after the endpoint URL, "1" for the next, …) — path segments are matched positionally, not by name. To carry a value into the body or a header instead, leave this blocked and add a field mapping on the target sourced from this attribute.'}, 'validators': {'type': 'array', 'items': {'enum': ['email', 'phone', 'int', 'double', 'bool', 'string', 'array', 'dictionary', 'range', 'oneOf', 'type', 'nil', 'not', 'empty', 'arrayType', 'arrayLength', 'arraySubset', 'arrayIntersect', 'intString', 'doubleString', 'boolString', 'numberString', 'numberOneOf', 'stringLength', 'stringEmpty', 'stringJson', 'dictionaryString'], 'type': 'string'}, 'description': 'Validator names to run, in order. See params for any bounds/values they need.'}, 'description': {'type': 'string', 'description': 'Shown in the auto-generated OpenAPI doc.'}, 'defaultValue': {'description': 'Used when the attribute is absent and required=false. Any scalar.'}, 'attributeType': {'enum': ['string', 'int', 'double', 'bool', 'array', 'object'], 'type': 'string', 'description': 'Expected value type.'}}, 'additionalProperties': False}, 'description': 'Request validators. One entry per attribute; the Framework rejects callers whose payload fails the configured rules. Empty array = no validation.'}, 'httpMethod': {'enum': ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'], 'type': 'string', 'description': 'HTTP method callers must use. GET endpoints cannot declare a body attribute (see attributes[].in).'}, 'mockResponse': {'type': ['object', 'null'], 'properties': {'body': {'type': 'string', 'description': 'Literal response body.'}, 'statusCode': {'type': 'integer', 'maximum': 599, 'minimum': 100}, 'contentType': {'type': 'string', 'description': 'e.g. "application/json".'}}, 'description': 'Response returned in mock mode. Required when mock=true.', 'additionalProperties': False}, 'transformers': {'type': ['array', 'null'], 'items': {'type': 'object', 'required': ['type'], 'properties': {'type': {'enum': ['mergeFields', 'renameField', 'removeField', 'addField', 'mapValue', 'binaryToUrl'], 'type': 'string', 'description': 'mergeFields: from+to(+separator). renameField: from+to. removeField: field. addField: to+value. mapValue: field+mapping. binaryToUrl: ttlSeconds?+maxSizeMB? (both clamped server-side — omit for the server default).'}, 'params': {'type': ['object', 'null'], 'properties': {'to': {'type': 'string', 'description': 'Destination field — mergeFields / renameField / addField.'}, 'from': {'type': 'array', 'items': {'type': 'string'}, 'description': 'mergeFields (all sources) / renameField (first element is the source).'}, 'field': {'type': 'string', 'description': 'Target field — removeField / mapValue.'}, 'value': {'type': 'string', 'description': 'Constant value to set — addField.'}, 'mapping': {'type': 'object', 'description': 'Value lookup table — mapValue.', 'additionalProperties': {'type': 'string'}}, 'maxSizeMB': {'type': 'integer', 'minimum': 1, 'description': 'Max upload size in MB — binaryToUrl.'}, 'separator': {'type': 'string', 'description': 'Join separator — mergeFields (default " ").'}, 'ttlSeconds': {'type': 'integer', 'minimum': 1, 'description': 'Temp file lifetime in seconds — binaryToUrl.'}}, 'description': 'Only the keys the chosen type reads are accepted; see the type description above.', 'additionalProperties': False}}, 'additionalProperties': False}, 'description': 'Endpoint-level request transformation pipeline, applied before any target-level transformers. Set to null to remove the override and inherit the line default (if the line has one); set to an empty array to explicitly apply no transformation even when the line has a default. Omit on update_endpoint to leave the existing value unchanged.'}, 'idempotencyEnabled': {'type': 'boolean', 'description': "When true, the Framework deduplicates on the caller's Idempotency-Key header. Default true."}}, 'description': 'Endpoint document (for create dry-run) or PATCH body (when endpointId is supplied).', 'additionalProperties': False}, 'endpointId': {'type': 'string', 'description': 'Optional: dry-run a PATCH against this endpoint UUID.'}, 'answerSample': {'type': ['object', 'array', 'string', 'number', 'boolean', 'null'], 'description': 'Optional: an answer payload, shaped as one a target would actually return. Drives answerMapping the same way, as answerMappingEvaluation. It cannot be inferred from sample — the two travel in opposite directions.'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey', 'newLineKey'], 'properties': {'name': {'type': 'string', 'description': 'Optional name for the copy (defaults to "<source name> (copy)").'}, 'lineKey': {'type': 'string', 'description': 'The source line key to copy.'}, 'commitMode': {'enum': ['draft', 'publish'], 'type': 'string', 'description': 'Defaults to publish. Draft writes require draftRevision.'}, 'newLineKey': {'type': 'string', 'description': 'New line key for the copy, e.g. "v2".'}, 'draftRevision': {'type': 'integer', 'description': 'Current line draft revision, required for draft writes.'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey', 'sample', 'deliveryMode', 'draftRevision'], 'properties': {'sample': {'type': 'object', 'description': 'A sample inbound request body, shaped as one a real caller would send — one JSON field per key.'}, 'lineKey': {'type': 'string', 'description': 'The line key to draft the generated endpoint under.'}, 'targetUrl': {'type': 'string', 'description': 'The target URL. Required when targetSample is used; ignored when targetDocument is used (its servers[] entry wins).'}, 'deliveryMode': {'enum': ['async', 'sync', 'stream'], 'type': 'string', 'description': 'The caller contract this endpoint offers: async acceptance with later outcomes, one sync reply, or a stream.'}, 'targetSample': {'type': 'object', 'description': "A raw sample of the target's own request body, used instead of targetDocument when there is no spec to read. Requires targetUrl."}, 'draftRevision': {'type': 'integer', 'description': "The line's current draft revision (0 for a line with no draft yet) — see get_line_draft."}, 'targetDocument': {'type': 'string', 'description': "The target's OpenAPI 3.x document (YAML or JSON). Mutually exclusive with targetSample; must describe exactly one operation."}, 'targetFilename': {'type': 'string', 'description': 'Filename hint for targetDocument, to decide YAML vs JSON. Defaults to "target.json".'}, 'targetHttpMethod': {'type': 'string', 'description': 'HTTP method for the target when using targetSample. Defaults to POST.'}}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'oneOf': [{'required': ['id']}, {'required': ['requestId']}], 'properties': {'id': {'type': 'string', 'description': 'Dead-letter entry id, e.g. "1717930000000-0" (as returned by list_dlq). Changes on every retry — prefer requestId to track an entry across replays.'}, 'requestId': {'type': 'string', 'description': "The UUID the relay returned in its 202, or from list_requests / list_dlq rows. Stable across retries. Returns every fanned-out target's DLQ entry for this request. Provide exactly one of id / requestId."}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey', 'endpointId'], 'properties': {'lineKey': {'type': 'string', 'description': 'The line key, e.g. "v1".'}, 'endpointId': {'type': 'string', 'description': 'The endpoint UUID.'}}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'required': ['lineKey'], 'properties': {'lineKey': {'type': 'string', 'description': 'The line key, e.g. "v1".'}}}
Eingabeschema
{'type': 'object', 'properties': {'window': {'enum': ['hour', 'day', 'week', 'month'], 'type': 'string', 'description': 'Time horizon. Defaults to "day". "week"/"month" require a paid plan; otherwise the server returns "day" with planGated=true.'}, 'targetId': {'type': 'string', 'description': 'Optional outbound target UUID (from get_endpoint targets). When set, the series aggregate the per-attempt rows for that target instead of the project-wide inbound rows.'}, 'endpointId': {'type': 'string', 'description': 'Optional endpoint UUID (from list_endpoints / get_endpoint). When set, the series aggregate inbound request rows for that endpoint only. Mutually exclusive with targetId.'}}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'required': ['requestId'], 'properties': {'requestId': {'type': 'string', 'description': 'UUID returned by the relay in 202 responses or visible in list_requests rows.'}}}
Eingabeschema
{'type': 'object', 'required': ['requestId'], 'properties': {'requestId': {'type': 'string', 'description': 'UUID returned by the relay in 202 responses or visible in list_requests rows.'}}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'required': ['email', 'role'], 'properties': {'role': {'enum': ['editor', 'viewer', 'billing'], 'type': 'string', 'description': 'Role to assign on acceptance.'}, 'email': {'type': 'string', 'description': 'Email address to invite.'}}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'maximum': 200, 'minimum': 1, 'description': 'Page size. Default 50.'}, 'since': {'type': 'integer', 'description': 'Lower bound on createdAt (unix ms). Inclusive.'}, 'until': {'type': 'integer', 'description': 'Upper bound on createdAt (unix ms). Inclusive.'}, 'action': {'type': 'string', 'description': 'Exact action match, e.g. "endpoint.updated", "target.created", "key.revoked".'}, 'offset': {'type': 'integer', 'minimum': 0, 'description': 'Page offset. Default 0.'}, 'entityId': {'type': 'string', 'description': 'Exact entity id (UUID or stream id depending on entityType).'}, 'entityType': {'type': 'string', 'description': 'Exact entity type, e.g. "endpoint", "target", "line", "key".'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey'], 'properties': {'lineKey': {'type': 'string', 'description': 'The line key, e.g. "v1".'}}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'maximum': 200, 'minimum': 1, 'description': 'Page size. Default 50.'}, 'offset': {'type': 'integer', 'minimum': 0, 'description': 'Page offset. Default 0.'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey'], 'properties': {'lineKey': {'type': 'string', 'description': 'The line key, e.g. "v1".'}}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'required': ['slug'], 'properties': {'slug': {'type': 'string', 'description': 'The slug of a project you own.'}}}
Eingabeschema
{'type': 'object', 'properties': {'path': {'type': 'string', 'description': 'Substring of the request path (e.g. "/webhook"). LIKE-matched.'}, 'limit': {'type': 'integer', 'maximum': 200, 'minimum': 1, 'description': 'Page size. Default 50.'}, 'since': {'type': 'integer', 'description': 'Lower bound on ts (unix ms). Inclusive.'}, 'until': {'type': 'integer', 'description': 'Upper bound on ts (unix ms). Inclusive.'}, 'method': {'type': 'string', 'description': 'HTTP method (POST, GET, …). Case-insensitive.'}, 'offset': {'type': 'integer', 'minimum': 0, 'description': 'Page offset. Default 0.'}, 'status': {'type': 'integer', 'description': 'Exact HTTP status code (e.g. 404).'}, 'targetOutcome': {'enum': ['success', 'permanent_failure', 'retry_scheduled', 'dlq'], 'type': 'string', 'description': 'Narrow to requests that produced at least one per-target attempt with this outcome. Use "dlq" to find requests with at least one target that ended up dead-lettered.'}}}
Eingabeschema
{'type': 'object', 'properties': {}}
Eingabeschema
{'type': 'object', 'required': ['lineKey'], 'properties': {'lineKey': {'type': 'string', 'description': 'The line key, e.g. "v1".'}}}
Eingabeschema
{'type': 'object', 'required': ['plan'], 'properties': {'plan': {'enum': ['free', 'pro', 'scale'], 'type': 'string', 'description': 'Target plan to preview a switch to.'}}}
Eingabeschema
{'type': 'object', 'required': ['slug'], 'properties': {'slug': {'type': 'string', 'description': 'The slug of a project you own.'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey', 'draftRevision'], 'properties': {'lineKey': {'type': 'string'}, 'draftRevision': {'type': 'integer'}}}
Eingabeschema
{'type': 'object', 'properties': {'email': {'type': 'string', 'description': 'Email address (alternative to memberId — removes the first matching member).'}, 'memberId': {'type': 'string', 'description': 'Member record UUID (from list_members).'}}}
Eingabeschema
{'type': 'object', 'required': ['slug', 'name'], 'properties': {'name': {'type': 'string', 'description': 'The new display name (1–100 chars).'}, 'slug': {'type': 'string', 'description': 'The slug of a project you own.'}}}
Eingabeschema
{'type': 'object', 'properties': {'email': {'type': 'string', 'description': 'Email address (alternative to memberId — targets the first matching pending invite).'}, 'memberId': {'type': 'string', 'description': 'Member record UUID (from list_members).'}}}
Eingabeschema
{'type': 'object', 'required': ['addonKey'], 'properties': {'addonKey': {'type': 'string', 'description': 'Add-on key to resume (e.g. "log_retention", "rpm_5000").'}}, 'additionalProperties': False}
Eingabeschema
{'type': 'object', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'Dead-letter entry id from list_dlq.'}}}
Eingabeschema
{'type': 'object', 'required': ['keyId'], 'properties': {'keyId': {'type': 'string', 'description': 'UUID of the predecessor key whose successor to reveal.'}}}
Eingabeschema
{'type': 'object', 'required': ['keyId'], 'properties': {'keyId': {'type': 'string', 'description': 'UUID of the key to revoke.'}}}
Eingabeschema
{'type': 'object', 'required': ['slug', 'tokenId'], 'properties': {'slug': {'type': 'string', 'description': 'The slug of a project you own.'}, 'tokenId': {'type': 'string', 'description': 'The management token UUID (from create_project_token or list_project_tokens).'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey', 'revision'], 'properties': {'lineKey': {'type': 'string'}, 'revision': {'type': 'integer', 'minimum': 1}, 'confirmRevision': {'type': 'integer', 'minimum': 1, 'description': 'The currently-published revision number from the preview diff. Omit to preview only; include to apply.'}, 'confirmUnsigned': {'type': 'string', 'description': 'The preview diff\'s unsignedFingerprint. Required whenever confirmRevision is given: a target\'s retained signing secret expires on a clock, so this proves the confirm saw the same set of targets the preview named as coming back unsigned. A stale one is refused with "rollback_confirmation_conflict".'}}}
Eingabeschema
{'type': 'object', 'required': ['keyId'], 'properties': {'keyId': {'type': 'string', 'description': 'UUID of the key to rotate.'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey', 'draftRevision', 'scheduledAt'], 'properties': {'lineKey': {'type': 'string'}, 'scheduledAt': {'type': 'string'}, 'draftRevision': {'type': 'integer'}}}
Eingabeschema
{'type': 'object', 'required': ['enabled'], 'properties': {'enabled': {'type': 'boolean', 'description': 'true to enable the burst window; false to disable.'}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey', 'enabled'], 'properties': {'enabled': {'type': 'boolean', 'description': "true to publish the line's public docs; false to take them down."}, 'lineKey': {'type': 'string', 'description': 'The line key, e.g. "v1".'}, 'commitMode': {'enum': ['draft', 'publish'], 'type': 'string', 'description': 'Defaults to publish. Draft writes require draftRevision.'}, 'draftRevision': {'type': 'integer', 'description': 'Current line draft revision, required for draft writes.'}}}
Eingabeschema
{'type': 'object', 'properties': {'maxKeyTtlDays': {'type': ['integer', 'null']}, 'defaultKeyTtlDays': {'type': ['integer', 'null']}, 'editorsMayCreateNonExpiringKeys': {'type': 'boolean'}}}
Eingabeschema
{'type': 'object', 'required': ['role'], 'properties': {'role': {'enum': ['editor', 'viewer', 'billing'], 'type': 'string', 'description': 'The new role.'}, 'email': {'type': 'string', 'description': 'Email address (alternative to memberId — targets the first matching member).'}, 'memberId': {'type': 'string', 'description': 'Member record UUID (from list_members).'}}}
Eingabeschema
{'type': 'object', 'required': ['patterns'], 'properties': {'patterns': {'type': 'array', 'items': {'type': 'string'}, 'description': 'The full replacement list of allowed hosts, e.g. ["api.stripe.com", "*.internal.example.com"]. Must be a subset of the current outboundHostAllowlist.'}}}
Eingabeschema
{'type': 'object', 'required': ['enabled'], 'properties': {'enabled': {'type': 'boolean', 'description': 'True (the default) bills credits past your allowance and prepaid balance as overage; false slows the account to the free rate once its credits are gone instead, and nothing is refused. Turning it off still bills overage already used this billing cycle; turning it on bills only usage after the change.'}}}
Eingabeschema
{'type': 'object', 'required': ['rpmCeiling'], 'properties': {'rpmCeiling': {'type': ['integer', 'null'], 'minimum': 1, 'description': 'A positive integer to set the ceiling, or null to clear it.'}}}
Eingabeschema
{'type': 'object', 'required': ['plan'], 'properties': {'plan': {'enum': ['pro', 'scale'], 'type': 'string'}}}
Eingabeschema
{'type': 'object', 'required': ['eurCents'], 'properties': {'eurCents': {'type': 'integer', 'minimum': 1, 'description': 'Pack price in EUR cents, matching a pack returned by list_credit_packs.'}}}
Eingabeschema
{'type': 'object', 'required': ['addonKey'], 'properties': {'addonKey': {'type': 'string', 'description': 'Stable key from list_addons (e.g. "team_member", "rpm_2000", "log_retention", "file_storage").'}}}
Eingabeschema
{'type': 'object', 'required': ['slug'], 'properties': {'slug': {'type': 'string', 'description': 'The slug of a project you own.'}}}
Eingabeschema
{'type': 'object', 'required': ['addonKey'], 'properties': {'addonKey': {'type': 'string'}}}
Eingabeschema
{'type': 'object', 'required': ['credentialId'], 'properties': {'auth': {'type': 'object', 'description': 'Same shape as create_credential. Omit to keep the existing auth entirely.'}, 'name': {'type': 'string', 'description': 'New name. Omit to keep the existing one.'}, 'credentialId': {'type': 'string', 'description': 'UUID of the credential (from list_credentials).'}, 'destinationHost': {'type': 'string', 'description': "Permanent — may only restate the credential's current host (omit it, or send back what list_credentials reported). Any other value is refused; a credential is never re-aimed, it is replaced."}}}
Eingabeschema
{'type': 'object', 'required': ['lineKey', 'endpointId', 'patch'], 'properties': {'patch': {'type': 'object', 'properties': {'url': {'type': 'string', 'pattern': '^/[A-Za-z0-9/_\\-{}]*$', 'description': 'Path under the line, e.g. "/webhook". Must start with "/" and contain only [A-Za-z0-9/_-{}].'}, 'mock': {'type': 'boolean', 'description': 'When true, callers receive mockResponse without fan-out to targets. Targets are saved but not invoked.'}, 'name': {'type': 'string', 'minLength': 1, 'description': 'Human-readable label for the endpoint.'}, 'strict': {'type': 'boolean', 'description': 'When true, validation rejects any attribute not declared in attributes[]. Default false.'}, 'targets': {'type': 'array', 'items': {'type': 'object', 'required': ['name', 'targetUrl', 'auth', 'deliveryMode'], 'properties': {'id': {'type': 'string', 'description': 'Returned on reads. Send it back unchanged to update that target and keep its stored secrets. Targets are matched by id; without one, by the same name and targetUrl; without either, a patch to the target in the same position keeps its secrets, as long as the list keeps its length, the patch does not change both its name and targetUrl, and a changed targetUrl stays on the same host. Any other target is new and must carry its own secrets.'}, 'auth': {'type': 'object', 'required': ['type'], 'properties': {'key': {'type': 'string', 'description': 'Required when type=apiKeyHeader or type=apiKeyQuery or type=publicPrivateKey.'}, 'type': {'enum': ['none', 'bearer', 'basic', 'apiKeyHeader', 'apiKeyQuery', 'publicPrivateKey'], 'type': 'string'}, 'token': {'type': 'string', 'description': 'Required when type=bearer.'}, 'secret': {'type': 'string', 'description': 'Required when type=publicPrivateKey.'}, 'password': {'type': 'string', 'description': 'Required when type=basic.'}, 'username': {'type': 'string', 'description': 'Required when type=basic.'}, 'paramName': {'type': 'string', 'description': 'Required when type=apiKeyQuery.'}, 'headerName': {'type': 'string', 'description': 'Required when type=apiKeyHeader.'}}, 'description': 'Outbound auth applied to the request. On reads, secrets are redacted to "***" — round-trip the sentinel to keep the stored secret. Ignored when credentialVaultEntryId is set.', 'additionalProperties': False}, 'name': {'type': 'string', 'description': 'Display name for the target.'}, 'mapping': {'type': 'array', 'items': {'type': 'object', 'required': ['sourceIn', 'sourceName', 'targetIn', 'targetName'], 'properties': {'sourceIn': {'enum': ['body', 'query', 'header', 'path'], 'type': 'string'}, 'targetIn': {'enum': ['body', 'query', 'header'], 'type': 'string'}, 'template': {'type': 'string', 'description': 'Optional templated value (e.g. "Bearer {value}").'}, 'sourceName': {'type': 'string', 'description': 'Inbound field name to read.'}, 'targetName': {'type': 'string', 'description': 'Outbound field name to write.'}}, 'additionalProperties': False}, 'description': 'Optional transformer rules. Each rule moves or renames a field from the inbound request to the outbound one.'}, 'targetUrl': {'type': 'string', 'format': 'uri', 'description': 'Outbound URL. Cannot point back to this project (the Framework rejects relay loops).'}, 'callbackURL': {'type': 'string', 'format': 'uri', 'description': "Pushed once this target's delivery reaches a terminal status — see get_receipts' callbackState. Must be https. Meaningful for async targets only — refused on sync/stream. Cannot point back into this project (the same relay-loop rule as targetUrl) and must be inside the project's outbound host allowlist when one is set. Unset = the customer polls the receipt instead."}, 'retryPolicy': {'type': ['object', 'null'], 'properties': {'retryOn': {'type': 'array', 'items': {'type': 'integer', 'maximum': 599, 'minimum': 100}, 'description': 'HTTP status codes that trigger a retry. Default [429, 500, 502, 503, 504].'}, 'maxAttempts': {'type': 'integer', 'maximum': 14, 'minimum': 1, 'description': 'Total delivery attempts, counting the first. 1 fails fast: one try, then the dead-letter queue. Higher values keep retrying with a widening gap between tries — at the default backoffMultiplier, roughly under a minute at 4, a few minutes at 7, about an hour at 10, a few hours at 14. Anything still undelivered lands in the dead-letter queue. Defaults to 14.'}, 'backoffMultiplier': {'type': 'number', 'maximum': 5, 'minimum': 1, 'description': 'How sharply the gap between tries widens. Higher spends the same attempts over a longer stretch. Defaults to 2.0.'}}, 'description': 'Async retry policy. Ignored unless deliveryMode=async. Leave it unset (null) and the platform default applies, which behaves the same as maxAttempts at its maximum. get_endpoint reports which is in effect: this object when set, null when the platform default applies.', 'additionalProperties': False}, 'syncTimeout': {'type': 'integer', 'maximum': 90, 'minimum': 1, 'description': 'Seconds the caller waits for a sync target. Ignored unless deliveryMode=sync.'}, 'deliveryMode': {'enum': ['async', 'sync', 'stream'], 'type': 'string', 'description': 'async = queued + retried (default); sync = caller waits up to syncTimeout for the target response; stream = SSE pass-through (max 1 per endpoint).'}, 'transformers': {'type': 'array', 'items': {'type': 'object', 'required': ['type'], 'properties': {'type': {'enum': ['mergeFields', 'renameField', 'removeField', 'addField', 'mapValue', 'binaryToUrl'], 'type': 'string', 'description': 'mergeFields: from+to(+separator). renameField: from+to. removeField: field. addField: to+value. mapValue: field+mapping. binaryToUrl: ttlSeconds?+maxSizeMB? (both clamped server-side — omit for the server default).'}, 'params': {'type': ['object', 'null'], 'properties': {'to': {'type': 'string', 'description': 'Destination field — mergeFields / renameField / addField.'}, 'from': {'type': 'array', 'items': {'type': 'string'}, 'description': 'mergeFields (all sources) / renameField (first element is the source).'}, 'field': {'type': 'string', 'description': 'Target field — removeField / mapValue.'}, 'value': {'type': 'string', 'description': 'Constant value to set — addField.'}, 'mapping': {'type': 'object', 'description': 'Value lookup table — mapValue.', 'additionalProperties': {'type': 'string'}}, 'maxSizeMB': {'type': 'integer', 'minimum': 1, 'description': 'Max upload size in MB — binaryToUrl.'}, 'separator': {'type': 'string', 'description': 'Join separator — mergeFields (default " ").'}, 'ttlSeconds': {'type': 'integer', 'minimum': 1, 'description': 'Temp file lifetime in seconds — binaryToUrl.'}}, 'description': 'Only the keys the chosen type reads are accepted; see the type description above.', 'additionalProperties': False}}, 'additionalProperties': False}, 'description': 'Request transformation pipeline applied to this target before delivery. Empty array = no transformation.'}, 'answerMapping': {'type': ['object', 'null'], 'description': "Reshapes this target's answer into what the caller receives — a tree of typed nodes conforming to the same published grammar as outgoingMapping. Refused on a stream target (deliveryMode=stream) — a stream's response is proxied straight through and never reshaped. null = no reshaping, the answer reaches the caller verbatim; paths, types and cycles are checked server-side."}, 'signingSecret': {'type': ['string', 'null'], 'description': 'Signs the body delivered to this target — separate from auth above, which authenticates OUTBOUND to the target. Shape: "whsec_" followed by base64 of 32 random bytes. Omit to leave unchanged; set to null to disable signing; set to your own whsec_-shaped value to use it verbatim (rejected otherwise, including an empty string — you hold this secret, so only you can supply it). On reads, a configured secret is redacted to "***" — round-trip that sentinel to keep the stored secret.'}, 'answerVariants': {'type': ['object', 'null'], 'description': 'The conditional form of answerMapping, for a target whose answers do not all share one shape: one mapping per reply instead of one for every reply. Requires "distinguishBy" naming the single thing that tells them apart ({"source":"status"}, {"source":"header","name":…} or {"source":"bodyField","path":…}), "variants" as an object keyed by the value it matches — an exact status like "429", a class like "4XX", or "default" — each holding a tree in the same grammar as answerMapping — or, where the caller should be answered with a status of your own, an object {"mapping": <tree>, "replyStatus": 402} — and "onNoMatch", which has no default and must be either "passthrough" (hand the vendor\'s answer back untouched) or "fail" (answer 422 naming the value that matched nothing). A replyStatus is what the caller sees and never what the delivery is measured or charged as; it must be a status that can carry a body (200–599, excluding 204, 205 and redirects), and setting one drops the vendor\'s own response headers, which describe the answer it replaced. A variant keyed on a status that carries no body (204, 205, 304) is reachable only when it sets one. Mutually exclusive with answerMapping on this target, and refused on a stream target for the same reason answerMapping is. A variant whose tree does not compile is refused when the line is published, not silently dropped. null = no reshaping.'}, 'outgoingMapping': {'type': ['object', 'null'], 'description': 'Reshapes the request into what this target expects — a tree of typed nodes conforming to the published grammar at "https://schemas.echorelay.dev/transform/mapping/v1.json" (its own $schema key must name that value). Mutually exclusive with mapping and transformers on this target, and with the endpoint\'s own transformers — the write is rejected if both are set. null = no reshaping (today\'s behaviour, and the only value this schema itself can validate; paths, types and cycles are checked server-side).'}, 'credentialVaultEntryId': {'type': 'string', 'description': "References a saved credential (see list_credentials/create_credential) instead of inline auth — the auth field above is ignored when this is set. Must belong to the same project. The credential is bound to a destination when it is created: targetUrl must be https and its host must match that credential's destinationHost, or the write is rejected."}}, 'additionalProperties': False}, 'description': 'Outbound destinations. Required unless mock=true. Each entry becomes one queue fan-out.'}, 'rateLimit': {'type': ['object', 'null'], 'required': ['requests', 'windowSeconds'], 'properties': {'requests': {'type': 'integer', 'minimum': 1, 'description': 'Requests allowed per window.'}, 'windowSeconds': {'type': 'integer', 'minimum': 1, 'description': 'Window size in seconds.'}}, 'description': 'Per-endpoint rate limit. Set to null to remove. Both fields required together.', 'additionalProperties': False}, 'allowedIPs': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Inbound IP allowlist, in CIDR notation (e.g. "203.0.113.0/24", "::1/128"). Empty array = allow all.'}, 'attributes': {'type': 'array', 'items': {'type': 'object', 'required': ['name', 'in', 'attributeType'], 'properties': {'id': {'type': 'string', 'format': 'uuid', 'description': 'Stable attribute id. Optional on create; generated when omitted.'}, 'in': {'enum': ['body', 'query', 'header', 'path'], 'type': 'string', 'description': 'Where the attribute is read from on the inbound request.'}, 'name': {'type': 'string', 'description': 'Attribute field name (matches the inbound payload key).'}, 'params': {'type': 'object', 'description': 'Validator parameters. Recognised keys: min, max (range/stringLength/arrayLength), values (oneOf/arraySubset/arrayIntersect), numbers (numberOneOf), type (typeValidator/arrayType).', 'additionalProperties': True}, 'schema': {'type': ['object', 'null'], 'required': ['type'], 'properties': {'type': {'enum': ['string', 'int', 'double', 'bool', 'array', 'object'], 'type': 'string'}, 'items': {'type': 'object', 'description': 'For type=array: the element schema (same form).'}, 'maxItems': {'type': 'integer', 'minimum': 0}, 'minItems': {'type': 'integer', 'minimum': 0}, 'required': {'type': 'array', 'items': {'type': 'string'}, 'description': 'For type=object: property names that must be present.'}, 'properties': {'type': 'object', 'description': 'For type=object: map of property name → schema (same form).'}, 'additionalProperties': {'type': 'boolean', 'description': 'For type=object: when false, reject members not in properties.'}}, 'description': 'Optional precise JSON shape, enforced recursively alongside validators[]. scalar: {type}. array: {type:"array", items:<schema>, minItems?, maxItems?}. object: {type:"object", properties:{name:<schema>}, required?:[...], additionalProperties?:bool}. type must match attributeType.', 'additionalProperties': True}, 'logging': {'enum': ['loggable', 'obscured', 'nonLoggable'], 'type': 'string', 'description': 'How the value appears in the request log. obscured = masked; nonLoggable = stripped entirely.'}, 'required': {'type': 'boolean', 'description': 'When true, requests missing this attribute are rejected.'}, 'forwarding': {'enum': ['blocked', 'forwardInPlace'], 'type': 'string', 'description': 'Only meaningful for in=query or in=path. blocked (default): validated, never sent to the target. forwardInPlace: sent to the target in the same location — a query attribute as a query parameter, a path attribute as a path segment. A path attribute forwards only when its name is its own zero-based segment position ("0" for the first segment after the endpoint URL, "1" for the next, …) — path segments are matched positionally, not by name. To carry a value into the body or a header instead, leave this blocked and add a field mapping on the target sourced from this attribute.'}, 'validators': {'type': 'array', 'items': {'enum': ['email', 'phone', 'int', 'double', 'bool', 'string', 'array', 'dictionary', 'range', 'oneOf', 'type', 'nil', 'not', 'empty', 'arrayType', 'arrayLength', 'arraySubset', 'arrayIntersect', 'intString', 'doubleString', 'boolString', 'numberString', 'numberOneOf', 'stringLength', 'stringEmpty', 'stringJson', 'dictionaryString'], 'type': 'string'}, 'description': 'Validator names to run, in order. See params for any bounds/values they need.'}, 'description': {'type': 'string', 'description': 'Shown in the auto-generated OpenAPI doc.'}, 'defaultValue': {'description': 'Used when the attribute is absent and required=false. Any scalar.'}, 'attributeType': {'enum': ['string', 'int', 'double', 'bool', 'array', 'object'], 'type': 'string', 'description': 'Expected value type.'}}, 'additionalProperties': False}, 'description': 'Request validators. One entry per attribute; the Framework rejects callers whose payload fails the configured rules. Empty array = no validation.'}, 'httpMethod': {'enum': ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'], 'type': 'string', 'description': 'HTTP method callers must use. GET endpoints cannot declare a body attribute (see attributes[].in).'}, 'mockResponse': {'type': ['object', 'null'], 'properties': {'body': {'type': 'string', 'description': 'Literal response body.'}, 'statusCode': {'type': 'integer', 'maximum': 599, 'minimum': 100}, 'contentType': {'type': 'string', 'description': 'e.g. "application/json".'}}, 'description': 'Response returned in mock mode. Required when mock=true.', 'additionalProperties': False}, 'transformers': {'type': ['array', 'null'], 'items': {'type': 'object', 'required': ['type'], 'properties': {'type': {'enum': ['mergeFields', 'renameField', 'removeField', 'addField', 'mapValue', 'binaryToUrl'], 'type': 'string', 'description': 'mergeFields: from+to(+separator). renameField: from+to. removeField: field. addField: to+value. mapValue: field+mapping. binaryToUrl: ttlSeconds?+maxSizeMB? (both clamped server-side — omit for the server default).'}, 'params': {'type': ['object', 'null'], 'properties': {'to': {'type': 'string', 'description': 'Destination field — mergeFields / renameField / addField.'}, 'from': {'type': 'array', 'items': {'type': 'string'}, 'description': 'mergeFields (all sources) / renameField (first element is the source).'}, 'field': {'type': 'string', 'description': 'Target field — removeField / mapValue.'}, 'value': {'type': 'string', 'description': 'Constant value to set — addField.'}, 'mapping': {'type': 'object', 'description': 'Value lookup table — mapValue.', 'additionalProperties': {'type': 'string'}}, 'maxSizeMB': {'type': 'integer', 'minimum': 1, 'description': 'Max upload size in MB — binaryToUrl.'}, 'separator': {'type': 'string', 'description': 'Join separator — mergeFields (default " ").'}, 'ttlSeconds': {'type': 'integer', 'minimum': 1, 'description': 'Temp file lifetime in seconds — binaryToUrl.'}}, 'description': 'Only the keys the chosen type reads are accepted; see the type description above.', 'additionalProperties': False}}, 'additionalProperties': False}, 'description': 'Endpoint-level request transformation pipeline, applied before any target-level transformers. Set to null to remove the override and inherit the line default (if the line has one); set to an empty array to explicitly apply no transformation even when the line has a default. Omit on update_endpoint to leave the existing value unchanged.'}, 'idempotencyEnabled': {'type': 'boolean', 'description': "When true, the Framework deduplicates on the caller's Idempotency-Key header. Default true."}}, 'description': 'Partial endpoint document — same shape as create_endpoint, every field optional.', 'additionalProperties': False}, 'lineKey': {'type': 'string', 'description': 'The line key.'}, 'commitMode': {'enum': ['draft', 'publish'], 'type': 'string', 'description': 'Defaults to publish. Draft writes require draftRevision.'}, 'endpointId': {'type': 'string', 'description': 'The endpoint UUID.'}, 'scheduledAt': {'type': 'string', 'description': 'Compatibility alias: stage this update then schedule its line.'}, 'draftRevision': {'type': 'integer', 'description': 'Current line draft revision, required for draft writes.'}}}
Letzte Tool-Änderungen
Ähnliche MCP-Server
shiply
Publishes and manages web applications with SQL databases, serverless functions, domains, email tests, client intake, contracts, …
Fine Structure
Builds and hosts full-stack applications from prompts and supports agent communication through WhatsApp and email.
mcp
Provisions and manages cloud instances, networks, storage, databases, backups, VPNs, application deployments, and autocoding-agen…
Supero
Builds, validates, publishes, tests, and deploys multi-tenant applications with schemas, CRUD operations, external data connector…
Replicate
Provides access to Replicate models, versions, collections, hardware, predictions, and deployments for running and managing hoste…
Relin
Configures webhook sources and destinations, monitors delivery health, investigates failures, manages retries, and replays events.
Scalix Cloud
Provides managed databases, SQL tools, container builds, persistent Linux machines, domains, scheduled functions, storage, and pr…
RationalBloks
Creates, deploys, manages, and searches schema-based REST API projects and Neo4j knowledge graphs across staging and production e…