{
  "openapi": "3.1.0",
  "info": {
    "title": "CredEx AI \u2014 Verification API",
    "description": "Multi-agent consensus verification for AI outputs. 5 independent verifiers (OpenAI, Google, Anthropic, xAI, DeepSeek) evaluate every submission. Only Merkle-root hashes are anchored to the XRP Ledger \u2014 your content never touches the blockchain.",
    "version": "2.2.0",
    "contact": {
      "email": "erike@credexai.live",
      "url": "https://credexai.live"
    }
  },
  "servers": [
    {
      "url": "https://credexai.live/api",
      "description": "Production"
    }
  ],
  "paths": {
    "/health": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "Health Check",
        "operationId": "health_check_health_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/v1/verify": {
      "post": {
        "tags": [
          "Consensus Verification API"
        ],
        "summary": "Quick Verify \u2014 One-Shot Post-Execution Verification",
        "description": "Verify any AI agent's output using Credex's multi-agent consensus protocol (one-shot mode).\n\n**How it works:**\n1. Your prompt and the agent's output are sent to multiple independent verifier agents (GPT-4.1-mini)\n2. Each verifier independently evaluates correctness, completeness, relevance, and quality\n3. Results are aggregated using majority voting (3+ of 5 = approved)\n4. A provenance certificate with SHA-256 hash is generated for auditability\n\nFor a more thorough two-step flow that can save credits by catching issues early, use:\n- `POST /v1/verify/pre` (before running your agent)\n- `POST /v1/verify/post` (after running your agent)\n\n**Pricing:** Free during beta. No payment required.\n\n**Authentication (optional):**\n- **Open mode:** No authentication required. 1,000 calls/day per IP.\n- **API key mode:** Include `X-API-Key: cxv_your_key_here` header. 10,000 calls/day. Get a free key at `/v1/verify/demo-key`.\n\n**Example:**\n```bash\ncurl -X POST https://credexai.live/api/v1/verify \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"prompt\": \"What is 2+2?\",\n    \"output\": \"4\",\n    \"verifier_count\": 3\n  }'\n```",
        "operationId": "verify_output_v1_verify_post",
        "parameters": [
          {
            "name": "X-API-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerifyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerifyResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerifyErrorResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerifyErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/verify/pre": {
      "post": {
        "tags": [
          "Consensus Verification API"
        ],
        "summary": "Step 1 \u2014 Pre-Execution Prompt Verification",
        "description": "**Step 1 of the two-step verification pipeline.** Verify your prompt BEFORE spending credits on agent execution.\n\nVerifiers evaluate:\n- Is the prompt clear and unambiguous?\n- Is the planned approach sound?\n- Will this produce the desired result?\n- Are there risks of wasted credits?\n\nIf the verdict is **\"proceed\"**, run your agent and then call `POST /v1/verify/post` with the `session_id`.\nIf the verdict is **\"revise\"**, check the `recommendations` array for specific suggestions to improve your prompt.\nIf the verdict is **\"abort\"**, the prompt has fundamental issues and should not be executed.\n\nThe `session_id` returned is valid for **1 hour** \u2014 giving you time to run your agent between steps.\n\n**Example:**\n```bash\ncurl -X POST https://credexai.live/api/v1/verify/pre \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"prompt\": \"Analyze AAPL stock data for the last 5 years and predict next quarter\",\n    \"context\": \"Using GPT-4 with web browsing. Budget: 500 CREDX.\",\n    \"verifier_count\": 5\n  }'\n```\n\n**Response includes `session_id` \u2014 save it for Step 2.**",
        "operationId": "verify_pre_v1_verify_pre_post",
        "parameters": [
          {
            "name": "X-API-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreVerifyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PreVerifyResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerifyErrorResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerifyErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/verify/post": {
      "post": {
        "tags": [
          "Consensus Verification API"
        ],
        "summary": "Step 2 \u2014 Post-Execution Output Verification",
        "description": "**Step 2 of the two-step verification pipeline.** Verify your agent's output AFTER execution.\n\nRequires a `session_id` from Step 1 (`POST /v1/verify/pre`). The verifiers evaluate the output\nagainst the original prompt stored in the session.\n\nReturns a **combined provenance certificate** covering both the pre and post verification steps,\nplus a `full_session` summary showing both verdicts and whether pre-verification caught issues early.\n\nSessions expire after **1 hour**.\n\n**Example:**\n```bash\ncurl -X POST https://credexai.live/api/v1/verify/post \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"session_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n    \"output\": \"Based on 5 years of AAPL data, the stock shows...\",\n    \"context\": \"Agent used Yahoo Finance API and ran 3 models\"\n  }'\n```",
        "operationId": "verify_post_v1_verify_post_post",
        "parameters": [
          {
            "name": "X-API-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostVerifyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostVerifyResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerifyErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Session not found or expired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerifyErrorResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerifyErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/v1/verify/health": {
      "get": {
        "tags": [
          "Consensus Verification API",
          "Consensus Verification API"
        ],
        "summary": "Health check for the verification endpoint",
        "description": "Check if the verification service is operational.",
        "operationId": "verify_health_v1_verify_health_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/v1/verify/async": {
      "post": {
        "summary": "Async Verify \u2014 Webhook Callback",
        "description": "Submit a verification request and receive the result asynchronously via webhook callback. Returns 202 Accepted immediately with a job_id. When consensus completes, CredEx POSTs the result to your webhook_url with HMAC-SHA256 signature.",
        "operationId": "verify_async",
        "tags": [
          "Consensus Verification API"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "prompt",
                  "output",
                  "webhook_url"
                ],
                "properties": {
                  "prompt": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 10000,
                    "description": "The original task/instruction given to the AI agent"
                  },
                  "output": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50000,
                    "description": "The agent's response/output to verify"
                  },
                  "context": {
                    "type": "string",
                    "maxLength": 10000,
                    "description": "Additional context, reasoning steps, or metadata",
                    "nullable": true
                  },
                  "verifier_count": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 5,
                    "default": 5,
                    "description": "Number of independent verifiers (1-5, default 5)"
                  },
                  "webhook_url": {
                    "type": "string",
                    "maxLength": 2048,
                    "description": "URL to receive the verification result via POST when complete",
                    "example": "https://your-app.com/hooks/credex-result"
                  },
                  "webhook_secret": {
                    "type": "string",
                    "maxLength": 256,
                    "description": "Shared secret for HMAC-SHA256 signature verification. If set, each delivery includes an X-CredEx-Signature header.",
                    "nullable": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Verification job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job_id": {
                      "type": "string",
                      "description": "Unique job identifier"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "processing"
                      ]
                    },
                    "webhook_url": {
                      "type": "string",
                      "description": "URL where results will be delivered"
                    },
                    "poll_url": {
                      "type": "string",
                      "description": "GET this URL to poll for results"
                    },
                    "estimated_time_ms": {
                      "type": "integer",
                      "description": "Estimated processing time"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/v1/verify/async/{job_id}": {
      "get": {
        "summary": "Poll Async Job Status",
        "description": "Check the status of an async verification job. Use as a fallback if your webhook endpoint is unavailable. Status values: processing, completed, delivered, failed.",
        "operationId": "get_async_job_status",
        "tags": [
          "Consensus Verification API"
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The job_id from the async verify response"
          }
        ],
        "responses": {
          "200": {
            "description": "Job status and result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "processing",
                        "completed",
                        "delivered",
                        "failed"
                      ]
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "result": {
                      "type": "object",
                      "nullable": true,
                      "description": "Full verification result (same schema as POST /v1/verify response). Available once status is completed/delivered."
                    },
                    "webhook_delivery": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "delivered",
                            "failed"
                          ]
                        },
                        "attempts": {
                          "type": "integer"
                        },
                        "last_status_code": {
                          "type": "integer",
                          "nullable": true
                        },
                        "delivered_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Job not found or expired (24-hour TTL)"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Agent": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100,
            "minLength": 1,
            "title": "Name"
          },
          "model_type": {
            "type": "string",
            "maxLength": 64,
            "minLength": 1,
            "title": "Model Type"
          },
          "hourly_rate": {
            "type": "number",
            "exclusiveMaximum": 10000.0,
            "exclusiveMinimum": 0.0,
            "title": "Hourly Rate",
            "description": "Hourly rate must be > 0 and < 10,000"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "default": ""
          },
          "capabilities": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Capabilities",
            "default": ""
          },
          "endpoint_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Endpoint Url",
            "default": ""
          },
          "id": {
            "type": "integer",
            "title": "Id"
          },
          "owner_id": {
            "type": "integer",
            "title": "Owner Id"
          },
          "status": {
            "$ref": "#/components/schemas/AgentStatus"
          },
          "reputation_score": {
            "type": "number",
            "title": "Reputation Score"
          },
          "api_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Api Key"
          },
          "xrpl_wallet_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Xrpl Wallet Address"
          },
          "credx_balance": {
            "type": "number",
            "title": "Credx Balance",
            "default": 0.0
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At"
          }
        },
        "type": "object",
        "required": [
          "name",
          "model_type",
          "hourly_rate",
          "id",
          "owner_id",
          "status",
          "reputation_score",
          "created_at"
        ],
        "title": "Agent"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "PostVerifyRequest": {
        "properties": {
          "session_id": {
            "type": "string",
            "minLength": 1,
            "title": "Session Id",
            "description": "Session ID from the pre-verification step",
            "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
          },
          "output": {
            "type": "string",
            "maxLength": 50000,
            "minLength": 1,
            "title": "Output",
            "description": "The agent's response/output to verify against the original prompt",
            "example": "Based on analysis of AAPL from 2021-2026..."
          },
          "context": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 10000
              },
              {
                "type": "null"
              }
            ],
            "title": "Context",
            "description": "Additional context about how the agent produced this output"
          }
        },
        "type": "object",
        "required": [
          "session_id",
          "output"
        ],
        "title": "PostVerifyRequest",
        "description": "Request body for post-execution output verification (Step 2)."
      },
      "PostVerifyResponse": {
        "properties": {
          "session_id": {
            "type": "string",
            "title": "Session Id",
            "description": "Session UUID linking both steps"
          },
          "verdict": {
            "type": "string",
            "title": "Verdict",
            "description": "Final verdict: 'approved', 'rejected', or 'mixed'"
          },
          "consensus_score": {
            "type": "string",
            "title": "Consensus Score",
            "description": "Consensus score, e.g. '5/5'"
          },
          "confidence": {
            "type": "number",
            "title": "Confidence",
            "description": "Overall confidence score (0-1)"
          },
          "verifier_results": {
            "items": {
              "$ref": "#/components/schemas/VerifierResult"
            },
            "type": "array",
            "title": "Verifier Results",
            "description": "Individual verifier assessments"
          },
          "provenance_certificate": {
            "$ref": "#/components/schemas/FullProvenanceCertificate",
            "description": "Combined certificate covering both pre and post verification"
          },
          "processing_time_ms": {
            "type": "integer",
            "title": "Processing Time Ms",
            "description": "Processing time in milliseconds"
          },
          "full_session": {
            "$ref": "#/components/schemas/FullSession",
            "description": "Summary of the complete two-step session"
          }
        },
        "type": "object",
        "required": [
          "session_id",
          "verdict",
          "consensus_score",
          "confidence",
          "verifier_results",
          "provenance_certificate",
          "processing_time_ms",
          "full_session"
        ],
        "title": "PostVerifyResponse",
        "description": "Response from post-execution verification (Step 2)."
      },
      "PreVerifyRequest": {
        "properties": {
          "prompt": {
            "type": "string",
            "maxLength": 10000,
            "minLength": 1,
            "title": "Prompt",
            "description": "The task/instruction you plan to give to the AI agent",
            "example": "Analyze the last 5 years of AAPL stock data and predict the next quarter's performance with confidence intervals."
          },
          "context": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 10000
              },
              {
                "type": "null"
              }
            ],
            "title": "Context",
            "description": "Additional context about the agent, constraints, or expected approach",
            "example": "Using GPT-4 with web browsing. Budget: 500 CREDX max."
          },
          "verifier_count": {
            "type": "integer",
            "maximum": 5.0,
            "minimum": 1.0,
            "title": "Verifier Count",
            "description": "Number of independent verifiers to use (1-5, default 5)",
            "default": 5
          }
        },
        "type": "object",
        "required": [
          "prompt"
        ],
        "title": "PreVerifyRequest",
        "description": "Request body for pre-execution prompt verification (Step 1)."
      },
      "PreVerifyResponse": {
        "properties": {
          "session_id": {
            "type": "string",
            "title": "Session Id",
            "description": "Session UUID \u2014 use this in Step 2 (POST /v1/verify/post)"
          },
          "verdict": {
            "type": "string",
            "title": "Verdict",
            "description": "Verdict: 'proceed', 'revise', or 'abort'"
          },
          "consensus_score": {
            "type": "string",
            "title": "Consensus Score",
            "description": "Consensus score, e.g. '4/5'"
          },
          "confidence": {
            "type": "number",
            "title": "Confidence",
            "description": "Overall confidence score (0-1)"
          },
          "verifier_results": {
            "items": {
              "$ref": "#/components/schemas/VerifierResult"
            },
            "type": "array",
            "title": "Verifier Results",
            "description": "Individual verifier assessments"
          },
          "recommendations": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Recommendations",
            "description": "Specific suggestions if verdict is 'revise' (empty if 'proceed')"
          },
          "processing_time_ms": {
            "type": "integer",
            "title": "Processing Time Ms",
            "description": "Processing time in milliseconds"
          }
        },
        "type": "object",
        "required": [
          "session_id",
          "verdict",
          "consensus_score",
          "confidence",
          "verifier_results",
          "recommendations",
          "processing_time_ms"
        ],
        "title": "PreVerifyResponse",
        "description": "Response from pre-execution verification (Step 1)."
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "VerifyErrorResponse": {
        "properties": {
          "detail": {
            "type": "string",
            "title": "Detail"
          },
          "code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code"
          }
        },
        "type": "object",
        "required": [
          "detail"
        ],
        "title": "VerifyErrorResponse",
        "description": "Error response."
      },
      "VerifyRequest": {
        "properties": {
          "prompt": {
            "type": "string",
            "maxLength": 10000,
            "minLength": 1,
            "title": "Prompt",
            "description": "The original task/instruction given to the AI agent",
            "example": "Summarize the key benefits of renewable energy in 3 bullet points."
          },
          "output": {
            "type": "string",
            "maxLength": 50000,
            "minLength": 1,
            "title": "Output",
            "description": "The agent's response/output to verify",
            "example": "1. Reduces carbon emissions\n2. Lower long-term costs\n3. Energy independence"
          },
          "context": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 10000
              },
              {
                "type": "null"
              }
            ],
            "title": "Context",
            "description": "Additional context, reasoning steps, or metadata"
          },
          "verifier_count": {
            "type": "integer",
            "maximum": 5.0,
            "minimum": 1.0,
            "title": "Verifier Count",
            "description": "Number of independent verifiers to use (1-5, default 5)",
            "default": 5
          }
        },
        "type": "object",
        "required": [
          "prompt",
          "output"
        ],
        "title": "VerifyRequest",
        "description": "Request body for one-shot post-execution verification."
      },
      "VerifyResponse": {
        "properties": {
          "verdict": {
            "type": "string",
            "title": "Verdict",
            "description": "Final verdict: 'approved', 'rejected', or 'mixed'"
          },
          "consensus_score": {
            "type": "string",
            "title": "Consensus Score",
            "description": "Consensus score, e.g. '4/5' or '5/5'"
          },
          "confidence": {
            "type": "number",
            "title": "Confidence",
            "description": "Overall confidence score (0-1)"
          },
          "verifier_results": {
            "items": {
              "$ref": "#/components/schemas/VerifierResult"
            },
            "type": "array",
            "title": "Verifier Results",
            "description": "Individual verifier assessments"
          },
          "provenance_certificate": {
            "$ref": "#/components/schemas/ProvenanceCertificate",
            "description": "Verification provenance certificate"
          },
          "processing_time_ms": {
            "type": "integer",
            "title": "Processing Time Ms",
            "description": "Total processing time in milliseconds"
          }
        },
        "type": "object",
        "required": [
          "verdict",
          "consensus_score",
          "confidence",
          "verifier_results",
          "provenance_certificate",
          "processing_time_ms"
        ],
        "title": "VerifyResponse",
        "description": "Response from one-shot post-execution verification."
      }
    }
  }
}