{
  "openapi": "3.1.0",
  "info": {
    "title": "Curbito Agent Access API",
    "version": "1.0.0",
    "description": "Read-only temporary street-access decisions for voice agents, navigation clients, and silent automations. Absence of a verified publication is never an all-clear."
  },
  "servers": [
    {
      "url": "https://curbito.com"
    }
  ],
  "paths": {
    "/api/v1/access/decisions": {
      "post": {
        "operationId": "checkAccess",
        "summary": "Check destination access for one arrival window",
        "description": "Accepts only a destination point and bounded time window. It does not accept an origin, full route, plate, VIN, or driver identity. Only approved, published, exact, fresh records may produce a verified action or navigation point.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AccessDecisionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Decision returned. A valid response may still require verification on arrival.",
            "headers": {
              "X-Curbito-Contract": {
                "schema": {
                  "type": "string",
                  "const": "curbito-access/1.0"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccessDecisionResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem"
          },
          "413": {
            "$ref": "#/components/responses/Problem"
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          },
          "503": {
            "description": "The publication repository is unavailable. The response remains fail-closed and contains no navigation destination.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccessDecisionResponse"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "responses": {
      "Problem": {
        "description": "The request could not be evaluated.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      }
    },
    "schemas": {
      "GeoJsonPoint": {
        "type": "object",
        "additionalProperties": false,
        "required": ["type", "coordinates"],
        "properties": {
          "type": {
            "type": "string",
            "const": "Point"
          },
          "coordinates": {
            "type": "array",
            "prefixItems": [
              {
                "type": "number",
                "minimum": -180,
                "maximum": 180
              },
              {
                "type": "number",
                "minimum": -90,
                "maximum": 90
              }
            ],
            "minItems": 2,
            "maxItems": 2
          }
        }
      },
      "AccessDecisionRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "contractVersion",
          "requestId",
          "destination",
          "window",
          "activity",
          "presentation"
        ],
        "properties": {
          "contractVersion": {
            "type": "string",
            "const": "curbito-access/1.0"
          },
          "requestId": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{3,119}$"
          },
          "destination": {
            "type": "object",
            "additionalProperties": false,
            "required": ["point"],
            "properties": {
              "point": {
                "$ref": "#/components/schemas/GeoJsonPoint"
              }
            }
          },
          "window": {
            "type": "object",
            "additionalProperties": false,
            "required": ["arrivalAt", "departureAt"],
            "properties": {
              "arrivalAt": {
                "type": "string",
                "format": "date-time",
                "description": "RFC 3339 timestamp with explicit Z or numeric offset."
              },
              "departureAt": {
                "type": "string",
                "format": "date-time",
                "description": "RFC 3339 timestamp with explicit Z or numeric offset."
              }
            }
          },
          "activity": {
            "type": "string",
            "enum": [
              "parking",
              "loading",
              "pickup_dropoff",
              "accessible_parking",
              "charging"
            ]
          },
          "audience": {
            "type": "string",
            "default": "public",
            "enum": [
              "resident",
              "business",
              "fleet",
              "city_service",
              "accessibility",
              "public"
            ]
          },
          "presentation": {
            "type": "object",
            "additionalProperties": false,
            "required": ["modes"],
            "properties": {
              "modes": {
                "type": "array",
                "minItems": 1,
                "maxItems": 3,
                "uniqueItems": true,
                "items": {
                  "type": "string",
                  "enum": ["voice", "navigation", "silent"]
                }
              },
              "locale": {
                "type": "string",
                "const": "en-US",
                "default": "en-US"
              }
            }
          }
        }
      },
      "Provenance": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "changeId",
          "revisionId",
          "revisionNumber",
          "externalRef",
          "projectRef",
          "timeZone",
          "authority",
          "sourceName",
          "issuedAt",
          "freshUntil",
          "publishedAt",
          "approvalReference",
          "contentFingerprint"
        ],
        "properties": {
          "changeId": { "type": "string" },
          "revisionId": { "type": "string" },
          "revisionNumber": { "type": "integer", "minimum": 1 },
          "externalRef": { "type": "string" },
          "projectRef": { "type": "string" },
          "timeZone": { "type": "string", "description": "IANA time zone published for the jurisdiction packet." },
          "authority": { "type": "string" },
          "sourceName": { "type": "string" },
          "sourceUrl": { "type": "string", "format": "uri" },
          "issuedAt": { "type": "string", "format": "date-time" },
          "freshUntil": { "type": "string", "format": "date-time" },
          "publishedAt": { "type": "string", "format": "date-time" },
          "approvalReference": { "type": "string" },
          "contentFingerprint": { "type": "string" }
        }
      },
      "AccessDecisionResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "contractVersion",
          "decisionId",
          "decisionRevision",
          "requestId",
          "serviceState",
          "evaluatedAt",
          "outcome",
          "verification",
          "instruction",
          "presentation",
          "execution",
          "provenance",
          "limitations",
          "privacy"
        ],
        "properties": {
          "contractVersion": {
            "type": "string",
            "const": "curbito-access/1.0"
          },
          "decisionId": { "type": "string" },
          "decisionRevision": { "type": "string" },
          "requestId": { "type": "string" },
          "serviceState": {
            "type": "string",
            "enum": ["operational", "unavailable"]
          },
          "evaluatedAt": { "type": "string", "format": "date-time" },
          "outcome": {
            "type": "string",
            "enum": ["reroute", "do_not_dispatch", "verify_on_arrival"]
          },
          "verification": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "result",
              "decisionEligible",
              "reasonCode",
              "authority",
              "freshness",
              "geometryMatch"
            ],
            "properties": {
              "result": {
                "type": "string",
                "enum": ["verified", "unverified"]
              },
              "decisionEligible": { "type": "boolean" },
              "reasonCode": {
                "type": "string",
                "enum": [
                  "PUBLISHED_ACCESS_CHANGE_WITH_ALTERNATIVE",
                  "PUBLISHED_ACCESS_CHANGE_NO_ALTERNATIVE",
                  "NO_VERIFIED_ACCESS_CHANGE",
                  "CONFLICTING_PUBLISHED_ACCESS_CHANGES",
                  "REPOSITORY_UNAVAILABLE"
                ]
              },
              "authority": {
                "type": "string",
                "enum": ["approved_publication", "none"]
              },
              "freshness": {
                "type": "string",
                "enum": ["current", "unknown"]
              },
              "geometryMatch": {
                "type": "string",
                "enum": ["exact", "unknown"]
              }
            }
          },
          "instruction": {
            "type": "object",
            "additionalProperties": false,
            "required": ["code", "validUntil", "revalidateAfter"],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "USE_VERIFIED_ALTERNATIVE",
                  "DO_NOT_USE_DESTINATION",
                  "VERIFY_POSTED_INSTRUCTIONS"
                ]
              },
              "validUntil": { "type": "string", "format": "date-time" },
              "revalidateAfter": { "type": "string", "format": "date-time" }
            }
          },
          "presentation": {
            "type": "object",
            "additionalProperties": false,
            "required": ["voice", "navigation", "silent"],
            "properties": {
              "voice": {
                "type": "object",
                "required": ["requested", "status"],
                "properties": {
                  "requested": { "type": "boolean" },
                  "status": { "type": "string", "enum": ["ready", "not_requested"] },
                  "text": { "type": "string" }
                }
              },
              "navigation": {
                "type": "object",
                "required": ["requested", "status"],
                "properties": {
                  "requested": { "type": "boolean" },
                  "status": { "type": "string", "enum": ["ready", "blocked", "not_requested"] },
                  "destination": {
                    "type": "object",
                    "required": ["zoneRef", "label", "point"],
                    "properties": {
                      "zoneRef": { "type": "string" },
                      "label": { "type": "string" },
                      "point": { "$ref": "#/components/schemas/GeoJsonPoint" }
                    }
                  },
                  "handoffs": {
                    "type": "object",
                    "additionalProperties": false,
                    "required": ["geoUri", "appleMapsUrl", "googleMapsUrl", "teslaFleetApi"],
                    "properties": {
                      "geoUri": { "type": "string" },
                      "appleMapsUrl": { "type": "string", "format": "uri" },
                      "googleMapsUrl": { "type": "string", "format": "uri" },
                      "teslaFleetApi": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": ["command", "endpointTemplate", "destination", "execution", "requirements"],
                        "properties": {
                          "command": { "type": "string", "const": "navigation_gps_request" },
                          "endpointTemplate": {
                            "type": "string",
                            "const": "/api/1/vehicles/{vin}/command/navigation_gps_request"
                          },
                          "destination": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": ["latitude", "longitude"],
                            "properties": {
                              "latitude": { "type": "number", "minimum": -90, "maximum": 90 },
                              "longitude": { "type": "number", "minimum": -180, "maximum": 180 }
                            }
                          },
                          "execution": { "type": "string", "const": "not_executed" },
                          "requirements": {
                            "type": "array",
                            "prefixItems": [
                              { "type": "string", "const": "vehicle_owner_authorization" },
                              { "type": "string", "const": "virtual_key_command_protocol" }
                            ],
                            "minItems": 2,
                            "maxItems": 2
                          }
                        }
                      }
                    }
                  }
                }
              },
              "silent": {
                "type": "object",
                "required": ["requested", "machineCode", "attentionRequired"],
                "properties": {
                  "requested": { "type": "boolean" },
                  "machineCode": {
                    "type": "string",
                    "enum": [
                      "USE_VERIFIED_ALTERNATIVE",
                      "DO_NOT_USE_DESTINATION",
                      "VERIFY_POSTED_INSTRUCTIONS"
                    ]
                  },
                  "attentionRequired": { "type": "boolean" }
                }
              }
            }
          },
          "execution": {
            "type": "object",
            "required": ["allowed", "prohibited", "humanConfirmationRequiredForWrites"],
            "properties": {
              "allowed": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": ["present", "prepare_navigation"]
                }
              },
              "prohibited": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": ["reserve", "pay", "report", "control_vehicle"]
                }
              },
              "humanConfirmationRequiredForWrites": {
                "type": "boolean",
                "const": true
              }
            }
          },
          "provenance": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Provenance"
            }
          },
          "limitations": {
            "type": "array",
            "items": { "type": "string" }
          },
          "privacy": {
            "type": "object",
            "required": [
              "requestPointStoredByContract",
              "acceptsOriginOrFullRoute",
              "containsPlateOrVin",
              "containsDriverIdentity",
              "storesTripTrail"
            ],
            "properties": {
              "requestPointStoredByContract": { "type": "boolean", "const": false },
              "acceptsOriginOrFullRoute": { "type": "boolean", "const": false },
              "containsPlateOrVin": { "type": "boolean", "const": false },
              "containsDriverIdentity": { "type": "boolean", "const": false },
              "storesTripTrail": { "type": "boolean", "const": false }
            }
          }
        }
      },
      "Problem": {
        "type": "object",
        "required": ["type", "title", "status", "code", "detail"],
        "properties": {
          "type": { "type": "string", "format": "uri" },
          "title": { "type": "string" },
          "status": { "type": "integer" },
          "code": { "type": "string" },
          "detail": { "type": "string" }
        }
      }
    }
  }
}
