1. Purpose
AI agents increasingly perform real-world tasks: booking services, verifying professionals, scheduling work, and paying on completion. Today every service endpoint describes itself differently. Agents cannot reliably determine what an endpoint can do, whether it is legitimate, or whether it will complete the job.
The Agent Service Schema defines a standard, machine-readable record describing a transactable service endpoint: what it can do, where it operates, how to invoke it, and — critically — how its claims have been verified and how fresh that verification is.
Non-goals. This specification does not define payment rails, identity protocols, or general agent-to-agent communication. It describes service endpoints so that any agent framework (MCP, A2A, or plain HTTP clients) can discover, evaluate, and transact with them uniformly.
2. Design principles
- One core, many extensions. Industry-specific fields live in versioned extension modules. They never enter the core.
- Transactions, not listings. A compliant record describes actions an agent can invoke — not merely a business that exists.
- Verification is first-class data. Independently checked claims carry their check method, source, timestamp, and expiry. Other claims remain explicitly self-asserted.
- Freshness is always disclosed. Stale data labeled stale is trustworthy. Stale data presented as fresh is not.
- Extend schema.org; don't fork it. Records map to schema.org types wherever one exists (see §4).
- Agents learn once. Query and invocation patterns are identical across every vertical.
3. Conformance levels
| Level | Name | Requirements |
|---|---|---|
| L1 | Described | A valid Service Record is published at a stable URL. Claims are self-asserted. |
| L2 | Callable | Every required action for the endpoint's capabilities responds to live probes with schema-valid output. Probe history is published. |
| L3 | Verified | Credential checks required by the applicable vertical extension (license, insurance, identity) have passed, and synthetic transactions complete end-to-end. |
| L4 | Monitored | Continuous probing plus trailing-90-day completion data (completion rate, dispute rate) is published and current. |
L1 describes a structurally valid published record; business claims remain self-asserted. Levels L2–L4 are computed by a verifier from evidence, never earned by setting a field. Domain control must be established before a verifier endorses the record. A failed required credential check or 7 consecutive days of failed probes sets status to suspended until re-verified (see §6). Suspended and unverified records use level 0; this is not an additional conformance tier.
4. The Service Record
The Service Record is the atomic unit of the schema. It is served as application/json at a stable URL and validated against the normative JSON Schema in Appendix A.
| Field | Required | Description |
|---|---|---|
schema_version | yes | Core spec version this record conforms to, e.g. "0.1". |
endpoint_id | yes | Globally unique id; reverse-DNS recommended, e.g. "com.stainmydeck". |
name | yes | Human-readable service name. |
description | yes | One-to-three sentence plain-language description. |
operator | yes | Object: legal_name, contact_email, website. |
capabilities | yes | Array of taxonomy nodes (§7), e.g. ["home.exterior.deck_staining"]. |
coverage | yes | Object: type (metro, region, national, or remote), areas[] (string area identifiers), exclusions[]. GeoJSON objects are deferred from v0.1. |
actions | yes | The transactable surface (§5). Object keyed by action name. |
pricing | yes | Object: model (fixed, hourly, quote_based, or tiered), currency, price_range {min,max} where known, notes. |
verification | yes | Verification block (§6). |
reputation | no | Object: completion_rate_90d, dispute_rate_90d, review_count, aggregate_rating. Required for L4. |
schema_org_type | no | Nearest schema.org type, e.g. "HomeAndConstructionBusiness". |
extensions | no | Namespaced vertical data, e.g. "extensions": {"legal": {...}} (§9). |
attestation | no | JWS signed verification claim (§10). |
record_updated_at | yes | ISO 8601 timestamp of last record change. |
Consumers MUST ignore unknown fields (forward compatibility, §12).
Illustrative excerpt — this abbreviated record omits required capability actions and verification evidence. Use Appendix B for the complete example:
{
"schema_version": "0.1",
"endpoint_id": "com.stainmydeck",
"name": "StainMyDeck",
"description": "On-demand deck staining quotes and booking.",
"operator": {"legal_name": "StainMyDeck LLC", "contact_email": "ops@stainmydeck.com", "website": "https://stainmydeck.com"},
"capabilities": ["home.exterior.deck_staining"],
"coverage": {"type": "metro", "areas": ["spokane-wa"], "exclusions": []},
"actions": {
"quote": {"url": "https://stainmydeck.com/api/v1/quote", "method": "POST", "auth": "none", "idempotent": true}
},
"pricing": {"model": "quote_based", "currency": "USD", "notes": "Final price confirmed after photo review."},
"verification": {"level": 3, "status": "verified", "last_verified_at": "2026-09-16T07:00:00Z"},
"schema_org_type": "HomeAndConstructionBusiness",
"record_updated_at": "2026-09-16T07:00:00Z"
}
A complete worked example is in Appendix B.
5. The standard action surface
Five standard actions. An endpoint implements the actions required by each of its capability nodes (§7); it MAY implement others. Every action descriptor:
{
"url": "https://example.com/api/v1/quote",
"method": "POST",
"auth": "none",
"input_schema": "https://agentserviceschema.org/schemas/v0.1/actions/quote-input.json",
"output_schema": "https://agentserviceschema.org/schemas/v0.1/actions/quote-output.json",
"idempotent": true,
"timeout_ms_recommended": 5000
}
| Action | Purpose | Core contract |
|---|---|---|
quote | Price estimate for a described job | Input: service details + location. Output: price_range {min,max}, currency, valid_until. SHOULD be idempotent and callable without auth. |
availability | When the service can be performed | Input: date range + location. Output: list of slots {start, end}. |
booking | Reserve the service | Input: slot or request details, customer contact, payment authorization where required. Output: booking_id, state, confirmed_for. |
status | Booking state | Input: booking_id. Output: current state from the booking state machine below, plus timestamps. |
cancel | Cancel a booking | Input: booking_id. Output: resulting state plus refund {amount, policy_applied}. |
The auth field accepts exactly one of none, api_key, or oauth2. Action URLs MUST be absolute HTTPS URIs or URI templates. Templates use RFC 6570 syntax; implementations must document path-variable bindings (for example, booking_id) before invocation. input_schema and output_schema are optional for an L1 record and required for L2+ action conformance. The action input/output schemas referenced in examples are planned; they are not shipped in this draft.
Booking state machine. status MUST return exactly one of:
requested, confirmed, in_progress, completed, cancelled, or disputed. Normal transitions are requested → confirmed → in_progress → completed. Cancellation may be entered from requested or confirmed; in-progress cancellation depends on a documented vertical policy. Disputed may be entered from confirmed, in_progress, or completed. Cancelled and disputed are terminal in this draft. Reopening or dispute resolution requires a future contract.
Vertical extensions MAY define additional actions (e.g. legal.verify_attorney), following the same descriptor format.
6. Verification model
{
"verification": {
"level": 3,
"status": "verified",
"checks": [
{"type": "liveness_probe", "result": "pass", "checked_at": "2026-09-16T06:00:00Z",
"source": "verifiedserviceschema.org/probes", "expires_at": "2026-09-17T06:00:00Z"},
{"type": "license_check", "result": "pass", "checked_at": "2026-09-01T06:00:00Z",
"source": "WA Dept. of Labor & Industries", "expires_at": "2026-11-30T06:00:00Z"}
],
"last_verified_at": "2026-09-16T06:00:00Z"
}
}
Status enum: unverified · self_asserted · probed · verified · suspended. A published L1 record is self_asserted; probed and verified statuses must be derived from independent checks. A JSON value alone is not proof of verification. last_verified_at is null when no independent full pass has occurred.
Check types: liveness_probe · schema_validation · synthetic_transaction · license_check · insurance_check · identity_check · domain_ownership.
Freshness rules:
liveness_probeexpires after 24h (L4 endpoints are probed continuously).- Credential checks (
license_check,insurance_check) expire per the issuing authority's cadence, or 90 days maximum. - Every check requires
expires_at. It must be later thanchecked_at; expired checks cannot support a level. Recompute the highest level whose required evidence is still current. Optional evidence does not reduce an otherwise supported level. last_verified_atis the timestamp of the most recent successful full pass.
Suspension. A failed credential check, or probes failing for 7 consecutive days, sets status to suspended. The endpoint remains listed (transparency) but is excluded from default ranking (§8) until re-verified.
7. Capability taxonomy — v0.1 seed
Taxonomy nodes are dotted paths. Each node defines: description, required actions, and applicable extensions. The v0.1 seed specifies the nodes below; additional branches are reserved. Node specification does not establish that a reference service is live or that its extension is Official. The home and auto extension contracts are still in development.
home.exterior.* (specified draft nodes)
| Capability | Description | Required actions | Extension |
|---|---|---|---|
home.exterior.deck_staining | Cleaning, prep, and stain application for wood decks. | quote, availability, booking, status, cancel | home |
home.exterior.deck_painting | Prep and paint application for wood decks. | quote, availability, booking, status, cancel | home |
home.exterior.fence_sealing | Cleaning and sealant application for wood fences. | quote, availability, booking, status, cancel | home |
home.exterior.gutter_cleaning | Debris removal and downspout flush. | quote, availability, booking, status, cancel | home |
home.exterior.hedge_trimming | Shaping and cutback of hedges and shrubs. | quote, availability, booking, status, cancel | home |
home.exterior.lawn_mowing | Recurring or one-time mowing. | quote, availability, booking, status, cancel | home |
home.exterior.lawn_edging | Edge cutting along walks, drives, beds. | quote, availability, booking, status, cancel | home |
home.exterior.mulching | Bed prep and mulch installation. | quote, availability, booking, status, cancel | home |
home.exterior.driveway_winter | Snow/ice salting and clearing for driveways. | quote, availability, booking, status, cancel | home |
home.exterior.garage_sealing | Concrete sealant for garage floors. | quote, availability, booking, status, cancel | home |
home.exterior.pressure_washing | Exterior surface pressure washing. | quote, availability, booking, status, cancel | home |
home.moving.*
| Capability | Description | Required actions | Extension |
|---|---|---|---|
home.moving.hot_tub | Specialty hot-tub relocation. | quote, availability, booking, status, cancel | home |
home.moving.furniture_single | Single-item furniture moves (e.g. couches). | quote, availability, booking, status, cancel | home |
home.events.*
| Capability | Description | Required actions | Extension |
|---|---|---|---|
home.events.bounce_house | Bounce house rental, delivery, setup. | quote, availability, booking, status, cancel | home |
home.events.projector_rental | Projector/screen rental and delivery. | quote, availability, booking, status, cancel | home |
fleet.*
| Capability | Description | Required actions | Extension |
|---|---|---|---|
fleet.detailing | On-site vehicle fleet detailing contracts. | quote, availability, booking, status, cancel | auto |
office.*
| Capability | Description | Required actions | Extension |
|---|---|---|---|
office.grounds_mowing | Commercial grounds mowing contracts. | quote, availability, booking, status, cancel | home |
Reserved branches (taxonomy paths allocated; extensions to follow):
beauty.* · legal.* · auto.* · pet.* · professional.* · medical.* · home.interior.* · home.systems.* (HVAC, plumbing, electrical).
New nodes are proposed through the extension process (§9). Node paths are stable once published: a node is never renamed, only superseded with a redirect record.
8. Ranking guidance for index operators
Any index implementing this schema and ranking endpoints for agents SHOULD order by, in priority:
- Conformance level (descending; suspended excluded from default results).
- Independently verified
reputation.completion_rate_90d(descending). A published number without validated provenance MUST NOT improve rank. The initial index policy uses independently verified L4 outcomes; unverified or absent outcome data sorts last within a level. - Probe p95 latency (ascending) — agents deprioritize slow endpoints.
- Price fit to the query (closest within budget first).
Paid placement is permitted only with machine-readable disclosure ("placement": "sponsored" on the record) and MUST NOT override verification ordering for safety-critical attributes. An index that sells rank without disclosure is non-conformant.
9. Extension mechanism
Vertical extensions are namespaced objects under the record's extensions key:
{
"extensions": {
"legal": {"extension_version": "0.1.0", "bar_numbers": ["00799999"], "jurisdictions": ["TX"]},
"home": {"extension_version": "0.1.0", "license_number": "STAINML123", "insured": true}
}
}
Each extension specification defines:
nameandversion(semver, independent of core).- A JSON Schema for its fields.
- The capability nodes it applies to.
- Additional required check types (e.g. legal requires
license_checkagainst the relevant bar authority). - Field-level freshness rules where stricter than core.
Lifecycle: Proposed → Reference implementation → Conformant (passes the conformance suite) → Official. Anyone may propose; only the publisher certifies Official status, with the conformance test suite as the gate.
Unofficial extensions use the x- prefix and MUST NOT claim conformance.
10. Identity, authentication, and attestations
Endpoint identity. endpoint_id SHOULD be reverse-DNS (com.stainmydeck) and MUST be unique within an index. Domain ownership is proven via DNS TXT (agent-service-verify=<token>) or /.well-known/agent-service.json serving the record.
Authentication. Declared per action: none (preferred for quote and availability), api_key for server-to-server, oauth2 for user-delegated booking. Auth requirements are part of the record so agents can plan accordingly.
Signed attestations. A verifier MAY issue a JWS (ES256) attestation:
{
"endpoint_id": "com.stainmydeck",
"capabilities": ["home.exterior.deck_staining"],
"conformance_level": 3,
"as_of": "2026-09-16T07:00:00Z",
"expires_at": "2026-09-17T06:00:00Z",
"issuer": "https://verifiedserviceschema.org"
}
Each verifier publishes its own key set at its trusted issuer origin's /.well-known/jwks.json. The planned Hottub, Inc. program issuer is https://verifiedserviceschema.org; the specification site is not the issuer. No production attestations or signing keys are issued in this preview.
Consumers MUST trust the issuer independently of the record, pin ES256, select an authorized key using kid, verify the signature, match the expected endpoint_id and capabilities, and check as_of and expires_at. Do not trust keys merely because an untrusted token points to them. Offline verification requires a previously obtained trusted key set. A valid signature proves what the issuer signed at that time; it does not establish current standing or guarantee a future job. Check a current report for revocation or suspension when current standing matters. An attestation MUST NOT outlive the earliest-expiring evidence required for its stated level.
11. Discovery
- Well-known record:
/.well-known/agent-service.jsonon the endpoint's domain MUST resolve to (or redirect to) its Service Record. - LLM-readable docs: endpoints SHOULD publish
llms.txtdescribing capabilities and linking the record. - MCP mapping:
search_services(capability, location, filters)andget_service_record(endpoint_id)map 1:1 onto this spec. - Registries: the submission format for any compliant registry is the Service Record itself — no secondary form.
12. Versioning and stability
schema_version: "0.1"identifies this draft's wire format. Publication releases use semver (initial draft release0.1.0-draft.1); extension releases use full semver independently. This draft may change before a stable release. From v1.0.0, changes within a major version are additive only: new optional fields, new actions, new taxonomy nodes.- Breaking changes increment the major version, with a minimum 12-month overlap during which the previous major remains served and valid.
- Records declare
schema_version; consumers MUST ignore unknown fields, which guarantees forward compatibility as the spec grows. - Taxonomy nodes are never renamed (§7); extensions version independently.
Appendix A: Normative JSON Schema — Service Record
$id: https://agentserviceschema.org/schemas/v0.1/service-record.json
JSON Schema draft 2020-12. Download the JSON Schema.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://agentserviceschema.org/schemas/v0.1/service-record.json",
"title": "Agent Service Schema — Service Record v0.1",
"type": "object",
"required": ["schema_version", "endpoint_id", "name", "description", "operator",
"capabilities", "coverage", "actions", "pricing", "verification",
"record_updated_at"],
"properties": {
"schema_version": {"type": "string", "const": "0.1"},
"endpoint_id": {"type": "string", "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$"},
"name": {"type": "string", "minLength": 1, "maxLength": 120},
"description": {"type": "string", "minLength": 1, "maxLength": 500},
"operator": {
"type": "object",
"required": ["legal_name", "contact_email", "website"],
"properties": {
"legal_name": {"type": "string"},
"contact_email": {"type": "string", "format": "email"},
"website": {"type": "string", "format": "uri"}
}
},
"capabilities": {
"type": "array", "minItems": 1,
"items": {"type": "string", "pattern": "^[a-z]+(\\.[a-z_]+)+$"}
},
"coverage": {
"type": "object",
"required": ["type", "areas"],
"properties": {
"type": {"enum": ["metro", "region", "national", "remote"]},
"areas": {"type": "array", "items": {"type": "string"}},
"exclusions": {"type": "array", "items": {"type": "string"}}
}
},
"actions": {
"type": "object", "minProperties": 1,
"propertyNames": {"pattern": "^[a-z][a-z0-9_-]*(\\.[a-z][a-z0-9_-]*)*$"},
"additionalProperties": {
"type": "object",
"required": ["url", "method", "auth"],
"properties": {
"url": {"type": "string", "format": "uri-template", "pattern": "^https://"},
"method": {"enum": ["GET", "POST", "PUT", "PATCH", "DELETE"]},
"auth": {"enum": ["none", "api_key", "oauth2"]},
"input_schema": {"type": "string", "format": "uri"},
"output_schema": {"type": "string", "format": "uri"},
"idempotent": {"type": "boolean"},
"timeout_ms_recommended": {"type": "integer", "minimum": 100}
}
}
},
"pricing": {
"type": "object",
"required": ["model", "currency"],
"properties": {
"model": {"enum": ["fixed", "hourly", "quote_based", "tiered"]},
"currency": {"type": "string", "pattern": "^[A-Z]{3}$"},
"price_range": {
"type": "object",
"properties": {
"min": {"type": "number", "minimum": 0},
"max": {"type": "number", "minimum": 0}
}
},
"notes": {"type": "string", "maxLength": 500}
}
},
"verification": {
"type": "object",
"required": ["level", "status", "last_verified_at"],
"oneOf": [
{"properties": {"level": {"const": 0}, "status": {"enum": ["unverified", "suspended"]}}},
{"properties": {"level": {"const": 1}, "status": {"const": "self_asserted"}}},
{"required": ["checks"], "properties": {"level": {"const": 2}, "status": {"const": "probed"}, "checks": {"minItems": 1}, "last_verified_at": {"type": "string"}}},
{"required": ["checks"], "properties": {"level": {"enum": [3, 4]}, "status": {"const": "verified"}, "checks": {"minItems": 1}, "last_verified_at": {"type": "string"}}}
],
"properties": {
"level": {"type": "integer", "minimum": 0, "maximum": 4},
"status": {"enum": ["unverified", "self_asserted", "probed", "verified", "suspended"]},
"checks": {
"type": "array",
"items": {
"type": "object",
"required": ["type", "result", "checked_at", "source", "expires_at"],
"properties": {
"type": {"enum": ["liveness_probe", "schema_validation", "synthetic_transaction",
"license_check", "insurance_check", "identity_check", "domain_ownership"]},
"result": {"enum": ["pass", "fail", "pending"]},
"checked_at": {"type": "string", "format": "date-time"},
"source": {"type": "string"},
"expires_at": {"type": "string", "format": "date-time"},
"evidence_url": {"type": "string", "format": "uri"}
}
}
},
"last_verified_at": {"type": ["string", "null"], "format": "date-time"},
"suspension_reason": {"type": "string"},
"suspended_at": {"type": "string", "format": "date-time"}
}
},
"reputation": {
"type": "object",
"properties": {
"completion_rate_90d": {"type": "number", "minimum": 0, "maximum": 1},
"dispute_rate_90d": {"type": "number", "minimum": 0, "maximum": 1},
"review_count": {"type": "integer", "minimum": 0},
"aggregate_rating": {"type": "number", "minimum": 0, "maximum": 5}
}
},
"schema_org_type": {"type": "string"},
"extensions": {"type": "object"},
"attestation": {"type": "string"},
"record_updated_at": {"type": "string", "format": "date-time"},
"placement": {"type": "string", "enum": ["sponsored"]}
},
"allOf": [
{
"if": {"required": ["verification"], "properties": {"verification": {"required": ["level"], "properties": {"level": {"const": 4}}}}},
"then": {"required": ["reputation"], "properties": {"reputation": {"required": ["completion_rate_90d", "dispute_rate_90d"]}}}
}
]
}
Appendix B: Worked example
Illustrative L3-shaped Service Record, frozen at 2026-09-16. This demonstrates data structure; it does not establish actual L3 conformance, validate a business, or provide live action schemas. No transactions should be initiated from this example.
{
"actions": {
"availability": {
"auth": "none",
"idempotent": true,
"method": "POST",
"timeout_ms_recommended": 3000,
"url": "https://stainmydeck.com/api/v1/availability"
},
"booking": {
"auth": "api_key",
"idempotent": false,
"method": "POST",
"timeout_ms_recommended": 8000,
"url": "https://stainmydeck.com/api/v1/bookings"
},
"cancel": {
"auth": "api_key",
"idempotent": true,
"method": "POST",
"timeout_ms_recommended": 5000,
"url": "https://stainmydeck.com/api/v1/bookings/{booking_id}/cancel"
},
"quote": {
"auth": "none",
"idempotent": true,
"input_schema": "https://agentserviceschema.org/schemas/v0.1/actions/quote-input.json",
"method": "POST",
"output_schema": "https://agentserviceschema.org/schemas/v0.1/actions/quote-output.json",
"timeout_ms_recommended": 5000,
"url": "https://stainmydeck.com/api/v1/quote"
},
"status": {
"auth": "api_key",
"idempotent": true,
"method": "GET",
"timeout_ms_recommended": 3000,
"url": "https://stainmydeck.com/api/v1/bookings/{booking_id}"
}
},
"capabilities": [
"home.exterior.deck_staining"
],
"coverage": {
"areas": [
"spokane-wa"
],
"exclusions": [],
"type": "metro"
},
"description": "On-demand deck staining: photo-based quotes, verified local contractors, online booking.",
"endpoint_id": "com.stainmydeck",
"extensions": {
"home": {
"bonded": true,
"crew_size": "2-3",
"extension_version": "0.1.0",
"insured": true,
"license_number": "STAINML123JD"
}
},
"name": "StainMyDeck",
"operator": {
"contact_email": "ops@stainmydeck.com",
"legal_name": "StainMyDeck LLC",
"website": "https://stainmydeck.com"
},
"pricing": {
"currency": "USD",
"model": "quote_based",
"notes": "Range covers typical residential decks; final price confirmed after photo review.",
"price_range": {
"max": 2500,
"min": 400
}
},
"record_updated_at": "2026-09-16T07:00:00Z",
"reputation": {
"aggregate_rating": 4.7,
"completion_rate_90d": 0.94,
"dispute_rate_90d": 0.02,
"review_count": 61
},
"schema_org_type": "HomeAndConstructionBusiness",
"schema_version": "0.1",
"verification": {
"checks": [
{
"checked_at": "2026-09-16T06:00:00Z",
"expires_at": "2027-09-16T06:00:00Z",
"result": "pass",
"source": "verifiedserviceschema.org",
"type": "domain_ownership"
},
{
"checked_at": "2026-09-16T06:00:00Z",
"expires_at": "2026-09-17T06:00:00Z",
"result": "pass",
"source": "verifiedserviceschema.org/probes",
"type": "liveness_probe"
},
{
"checked_at": "2026-09-16T06:00:00Z",
"expires_at": "2026-10-16T06:00:00Z",
"result": "pass",
"source": "verifiedserviceschema.org/conformance",
"type": "schema_validation"
},
{
"checked_at": "2026-09-15T06:00:00Z",
"expires_at": "2026-10-15T06:00:00Z",
"result": "pass",
"source": "verifiedserviceschema.org/conformance",
"type": "synthetic_transaction"
},
{
"checked_at": "2026-09-01T06:00:00Z",
"evidence_url": "https://secure.lni.wa.gov/verify/",
"expires_at": "2026-11-30T06:00:00Z",
"result": "pass",
"source": "WA Dept. of Labor & Industries",
"type": "license_check"
},
{
"checked_at": "2026-09-01T06:00:00Z",
"expires_at": "2026-11-30T06:00:00Z",
"result": "pass",
"source": "operator attestation + COI review",
"type": "insurance_check"
}
],
"last_verified_at": "2026-09-16T06:00:00Z",
"level": 3,
"status": "verified"
}
}
End of Core Specification v0.1 (Draft). Next: the legal, home, and beauty extension specifications, and the conformance test suite.