{
  "openapi": "3.1.0",
  "info": {
    "title": "Certiv Product API",
    "summary": "Authenticated product API for the Certiv AI agent governance platform.",
    "description": "Machine-readable OpenAPI 3.1 description of the Certiv product API served from the app host (app.certiv.ai) and hosted at https://api.certiv.ai. Certiv is an enterprise runtime-assurance platform for AI agents: it discovers agents, captures reasoning and tool calls, and enforces policy before risky actions execute.\n\nThis is the authenticated, account-scoped product API. Most endpoints require a bearer token issued to a Certiv organization account (see the bearerAuth security scheme and https://app.certiv.ai/auth.md). A small number of endpoints (health, token issuance, public counters) are unauthenticated and are marked with an empty security requirement. For the public lead-capture surface (request a demo, join the waitlist) see the separate spec at https://certiv.ai/openapi.json.\n\nTenant isolation: every authenticated request is scoped to the caller's organization. A token for one organization cannot read or act on another organization's data; isolation is enforced server-side.\n\nVersioning and deprecation: breaking changes ship under a new major version. Additive, non-breaking changes may ship without a version bump. Deprecated behavior is announced at least 90 days before removal via the Deprecation and Sunset response headers (RFC 8594). For the authoritative, always-current endpoint reference see https://docs.certiv.ai.",
    "version": "1.0.0",
    "termsOfService": "https://certiv.ai/terms/",
    "contact": {
      "name": "Certiv",
      "url": "https://certiv.ai/",
      "email": "hello@certiv.ai"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://certiv.ai/terms/"
    }
  },
  "servers": [
    {
      "url": "https://api.certiv.ai",
      "description": "Production product API"
    }
  ],
  "externalDocs": {
    "description": "Certiv product API and authentication documentation",
    "url": "https://docs.certiv.ai"
  },
  "tags": [
    {
      "name": "System",
      "description": "Health and readiness endpoints (unauthenticated)."
    },
    {
      "name": "Authentication",
      "description": "Obtain and refresh bearer tokens."
    },
    {
      "name": "Policies",
      "description": "Governance policy catalog (bearer auth)."
    },
    {
      "name": "Public counters",
      "description": "Public aggregate counters (unauthenticated)."
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/health": {
      "get": {
        "operationId": "getHealth",
        "tags": ["System"],
        "summary": "Health check",
        "description": "Liveness and readiness probe for the product API. Unauthenticated. Returns 200 when the service is healthy.",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is healthy.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                },
                "examples": {
                  "healthy": {
                    "value": {
                      "timeStampUTC": "2026-07-07T00:54:32.764064192Z",
                      "serviceStatus": "Running",
                      "serviceStartTimeUTC": "2026-07-07T00:24:39.150146745Z",
                      "uptime": 0.498,
                      "inboundInterfaces": [
                        {
                          "applicationName": "",
                          "connectionStatus": "Active",
                          "timeStampUTC": "2026-07-07T00:54:32.764070075Z",
                          "hostname": "api-server-d97458cc8-rtjft",
                          "address": "172.17.3.25",
                          "os": "linux"
                        }
                      ],
                      "outboundInterfaces": []
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Internal Server Error",
                      "error": "internal error"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/auth/login": {
      "post": {
        "operationId": "login",
        "tags": ["Authentication"],
        "summary": "Obtain a bearer token",
        "description": "Exchange account credentials for a bearer access token and refresh token. Unauthenticated. Present the returned access token in the Authorization header on subsequent product API calls.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authentication succeeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or expired bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Unauthorized",
                      "error": "Authentication required"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed request or a missing/invalid required parameter.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Bad Request",
                      "error": "organization_id is required"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Internal Server Error",
                      "error": "internal error"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/auth/refresh": {
      "post": {
        "operationId": "refreshToken",
        "tags": ["Authentication"],
        "summary": "Refresh a bearer token",
        "description": "Exchange a valid refresh token for a new access token. Unauthenticated at the header level; the refresh token is supplied in the request body.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefreshRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "New access token issued.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or expired bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Unauthorized",
                      "error": "Authentication required"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed request or a missing/invalid required parameter.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Bad Request",
                      "error": "organization_id is required"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Internal Server Error",
                      "error": "internal error"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/policies": {
      "get": {
        "operationId": "listPolicies",
        "tags": ["Policies"],
        "summary": "List governance policies",
        "description": "List policies in the caller's organization. Results are scoped to the caller's organization; another organization's policies are never returned. Requires a bearer token.",
        "responses": {
          "200": {
            "description": "Policies for the caller's organization.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Policy"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or expired bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Unauthorized",
                      "error": "Authentication required"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed request or a missing/invalid required parameter.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Bad Request",
                      "error": "organization_id is required"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Internal Server Error",
                      "error": "internal error"
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "organization_id",
            "in": "query",
            "required": true,
            "description": "The caller's organization id. Required on organization-scoped policy endpoints; the API only returns or mutates policies belonging to this organization.",
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "post": {
        "operationId": "createPolicy",
        "tags": ["Policies"],
        "summary": "Create a governance policy",
        "description": "Create a policy in the caller's organization. Requires a bearer token.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Policy"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Policy created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Policy"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or expired bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Unauthorized",
                      "error": "Authentication required"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed request or a missing/invalid required parameter.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Bad Request",
                      "error": "organization_id is required"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Internal Server Error",
                      "error": "internal error"
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "organization_id",
            "in": "query",
            "required": true,
            "description": "The caller's organization id. Required on organization-scoped policy endpoints; the API only returns or mutates policies belonging to this organization.",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/policies/{policy_id}": {
      "get": {
        "operationId": "getPolicy",
        "tags": ["Policies"],
        "summary": "Get a governance policy",
        "description": "Fetch a single policy by id from the caller's organization. Requires a bearer token.",
        "parameters": [
          {
            "name": "policy_id",
            "in": "path",
            "required": true,
            "description": "Policy identifier.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "organization_id",
            "in": "query",
            "required": true,
            "description": "The caller's organization id. Required on organization-scoped policy endpoints; the API only returns or mutates policies belonging to this organization.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested policy.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Policy"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or expired bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Unauthorized",
                      "error": "Authentication required"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The requested resource does not exist in the caller's organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Not Found",
                      "error": "policy not found"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed request or a missing/invalid required parameter.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Bad Request",
                      "error": "organization_id is required"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Internal Server Error",
                      "error": "internal error"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/waitlist/count": {
      "get": {
        "operationId": "getWaitlistCount",
        "tags": ["Public counters"],
        "summary": "Waitlist count",
        "description": "Public aggregate count of waitlist signups. Unauthenticated.",
        "security": [],
        "responses": {
          "200": {
            "description": "Aggregate count.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CountResponse"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "error": {
                    "value": {
                      "status": "Internal Server Error",
                      "error": "internal error"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Organization-scoped bearer token. Obtain a token via POST /auth/login or an organization API key from https://app.certiv.ai, then send it as `Authorization: Bearer <token>` over TLS on every authenticated request. A token only grants access to the organization it was issued for. See https://app.certiv.ai/auth.md."
      }
    },
    "responses": {},
    "schemas": {
      "HealthResponse": {
        "type": "object",
        "description": "Service health document returned by GET /health.",
        "required": [
          "serviceStatus",
          "timeStampUTC",
          "serviceStartTimeUTC",
          "uptime",
          "inboundInterfaces",
          "outboundInterfaces"
        ],
        "properties": {
          "timeStampUTC": {
            "type": "string",
            "format": "date-time",
            "description": "Time the probe was generated."
          },
          "serviceName": {
            "type": "string"
          },
          "serviceProvider": {
            "type": "string"
          },
          "serviceVersion": {
            "type": "string"
          },
          "serviceStatus": {
            "type": "string",
            "description": "Overall service status.",
            "examples": ["Running"]
          },
          "serviceStartTimeUTC": {
            "type": "string",
            "format": "date-time",
            "description": "Time the service started."
          },
          "uptime": {
            "type": "number",
            "description": "Service uptime in hours."
          },
          "inboundInterfaces": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HealthInterface"
            }
          },
          "outboundInterfaces": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HealthInterface"
            }
          }
        }
      },
      "LoginRequest": {
        "type": "object",
        "required": ["email", "password"],
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "description": "Account email address.",
            "examples": ["agent-operator@company.com"]
          },
          "password": {
            "type": "string",
            "format": "password",
            "description": "Account password."
          }
        }
      },
      "RefreshRequest": {
        "type": "object",
        "required": ["refresh_token"],
        "properties": {
          "refresh_token": {
            "type": "string",
            "description": "A valid refresh token previously issued by /auth/login."
          }
        }
      },
      "TokenResponse": {
        "type": "object",
        "required": ["access_token"],
        "properties": {
          "access_token": {
            "type": "string",
            "description": "Bearer access token to send as `Authorization: Bearer <token>`."
          },
          "refresh_token": {
            "type": "string",
            "description": "Refresh token used to obtain a new access token via /auth/refresh."
          },
          "token_type": {
            "type": "string",
            "description": "Token type.",
            "examples": ["Bearer"]
          },
          "expires_in": {
            "type": "integer",
            "description": "Access token lifetime in seconds.",
            "examples": [3600]
          }
        }
      },
      "Policy": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Policy identifier."
          },
          "name": {
            "type": "string",
            "description": "Human-readable policy name.",
            "examples": ["Block risky shell commands"]
          },
          "description": {
            "type": "string",
            "description": "What the policy governs."
          },
          "type": {
            "type": "string",
            "description": "Policy evaluation type.",
            "enum": ["deterministic", "intent"],
            "examples": ["intent"]
          },
          "organization_id": {
            "type": "string",
            "description": "Owning organization. Read-only; set from the caller's token and never cross-organization."
          }
        }
      },
      "CountResponse": {
        "type": "object",
        "required": ["count"],
        "properties": {
          "count": {
            "type": "integer",
            "description": "Aggregate count.",
            "examples": [1234]
          }
        }
      },
      "Error": {
        "type": "object",
        "description": "Standard JSON error envelope returned by the Certiv product API. Every handled error response uses application/json with this shape. `status` is the HTTP status text and `error` is a human-readable message.",
        "required": ["status", "error"],
        "properties": {
          "status": {
            "type": "string",
            "description": "HTTP status text (for example \"Unauthorized\", \"Bad Request\").",
            "examples": ["Unauthorized", "Bad Request"]
          },
          "error": {
            "type": "string",
            "description": "Human-readable error message.",
            "examples": ["Authentication required", "organization_id is required"]
          }
        }
      },
      "HealthInterface": {
        "type": "object",
        "description": "A single inbound or outbound service interface reported by the health probe.",
        "properties": {
          "applicationName": {
            "type": "string"
          },
          "connectionStatus": {
            "type": "string",
            "examples": ["Active"]
          },
          "timeStampUTC": {
            "type": "string",
            "format": "date-time"
          },
          "hostname": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "os": {
            "type": "string",
            "examples": ["linux"]
          }
        }
      }
    }
  }
}
