Endpoint Validation
Typed endpoint descriptors, health checks, and validation utilities for agent interoperability (v0.6.0).
Endpoint Validation
Added in v0.6.0, endpoint validation solves the "guess the endpoint" interoperability problem. Instead of relying on unstructured metadata strings, agents publish typed EndpointDescriptor objects that describe their HTTP endpoints, authentication requirements, and health checks. Consumers can validate these before depositing funds.
Why Endpoint Validation?
Without validation, a consumer might deposit SOL into an escrow for an agent whose endpoint is unreachable, returns HTML instead of JSON, or requires authentication the consumer cannot provide. Validation catches these issues before money is at risk.
Types
import type {
EndpointDescriptor,
HealthCheckDescriptor,
ToolManifestEntry,
AgentManifest,
EndpointValidationResult,
} from "@oobe-protocol-labs/synapse-sap-sdk";EndpointDescriptor
Machine-readable description of an agent's HTTP endpoint.
| Field | Type | Default | Description |
|---|---|---|---|
url | string | — | Full URL (e.g. https://api.example.com/x402) |
method | "GET" | "POST" | "PUT" | "DELETE" | "POST" | HTTP method |
contentType | string | "application/json" | Expected response Content-Type |
requiresAuth | boolean | false | Whether Authorization header is needed |
authType | "bearer" | "api-key" | "x402" | "none" | — | Auth type if requiresAuth |
requiresCSRF | boolean | false | Requires CSRF tokens |
requiresCookies | boolean | false | Requires browser cookies |
corsOrigins | string[] | — | Required CORS origins |
requiredHeaders | Record<string, string> | — | Additional required headers |
HealthCheckDescriptor
| Field | Type | Default | Description |
|---|---|---|---|
url | string | — | Health-check URL |
expectedStatus | number | 200 | Expected HTTP status code |
timeoutMs | number | 5000 | Timeout in milliseconds |
method | "GET" | "HEAD" | "GET" | HTTP method |
AgentManifest
Complete typed manifest replacing stringly-typed metadata.
| Field | Type | Description |
|---|---|---|
version | "1.0.0" | Manifest schema version |
wallet | string | Agent wallet (base58) |
name | string | Agent name |
description | string | Agent description |
endpoint | EndpointDescriptor | Primary x402 endpoint |
healthCheck | HealthCheckDescriptor? | Optional health-check config |
tools | ToolManifestEntry[] | All tools with typed schemas |
supportedNetworks | string[] | Network identifiers for x402 |
generatedAt | string | ISO 8601 timestamp |
Validation Functions
import {
validateEndpoint,
validateEndpointDescriptor,
validateHealthCheck,
validateAgentEndpoints,
} from "@oobe-protocol-labs/synapse-sap-sdk";Validate a Single URL
// Checks: reachability, JSON content-type, CORS headers, no HTML redirect.
// Measures latency. Returns an EndpointValidationResult.
const result = await validateEndpoint("https://api.example.com/x402", {
timeoutMs: 10_000, // default: 10,000 ms
retries: 1, // default: 1
method: "HEAD", // default: "HEAD" (faster than GET)
checkCors: true, // default: false
headers: { "X-Custom": "value" }, // optional extra headers
});
if (!result.reachable) {
console.error("Unreachable:", result.error);
}
if (!result.isSapCapable) {
console.warn("Not SAP-capable:", result.warnings);
// e.g. ["Endpoint returns HTML — may require CSRF or browser session"]
}
console.log("Latency:", result.latencyMs, "ms");Validate with Descriptor Metadata
// Uses the descriptor's method, required headers, and adds
// descriptor-specific warnings for CSRF/cookies.
const descriptor: EndpointDescriptor = {
url: "https://api.example.com/x402",
method: "POST",
contentType: "application/json",
requiresAuth: true,
authType: "x402",
requiresCSRF: false,
requiresCookies: false,
};
const result = await validateEndpointDescriptor(descriptor);
console.log("SAP-capable:", result.isSapCapable);Validate Health Check
const health: HealthCheckDescriptor = {
url: "https://api.example.com/health",
expectedStatus: 200,
timeoutMs: 5000,
};
const result = await validateHealthCheck(health);
if (!result.isSapCapable) {
console.error("Health check failed:", result.warnings);
}Validate All Agent Endpoints
// Validate primary endpoint + health check + tool-specific overrides in one call.
// Returns a Map<string, EndpointValidationResult>.
const results = await validateAgentEndpoints({
endpoint: manifest.endpoint,
healthCheck: manifest.healthCheck,
toolEndpoints: [
{ name: "jupiter-swap", endpoint: toolEndpointDescriptor },
],
});
// Results keyed by label:
// "primary" — primary endpoint
// "health" — health check
// "tool:jupiter-swap" — tool-specific endpoint
for (const [label, result] of results) {
console.log(`${label}: ${result.isSapCapable ? "OK" : "FAIL"} (${result.latencyMs}ms)`);
}EndpointValidationResult
| Field | Type | Description |
|---|---|---|
url | string | The URL tested |
reachable | boolean | Whether endpoint is reachable |
statusCode | number | HTTP status code (0 if unreachable) |
latencyMs | number | Response time in ms |
isJson | boolean | Response Content-Type is JSON |
hasCors | boolean | CORS headers present |
isSapCapable | boolean | Endpoint is SAP-compatible |
error | string? | Error message if failed |
warnings | string[] | Warnings (e.g. "requires CSRF") |
Best Practice: Validate Before Escrow
Always validate an agent's endpoint before depositing funds:
const result = await validateEndpoint(agentProfile.identity.x402Endpoint);
if (!result.isSapCapable) {
console.error("Agent endpoint not SAP-capable. Skipping escrow deposit.");
console.error("Warnings:", result.warnings);
return;
}
// Only deposit after successful validation
await client.x402.preparePayment(agentWallet, {
pricePerCall: 10_000,
deposit: 1_000_000,
});