{
  "openapi": "3.1.0",
  "info": {
    "title": "iSHANG Trust Network Hub API",
    "description": "Public and member-facing API of the iSHANG Trust Network Hub — the execution layer of the Trust Network Operating System (TNOS). Participants join Trust Circle Programs (TCPs), participate in campaigns, and receive Digital Entitlements (DEs). Authentication is token-based: POST /login.php or /verify-otp.php returns a bearer token sent as `Authorization: Bearer <token>`. Agent-facing surfaces: /llms.txt, /ontology.json, /docs/agents, /agents/onboarding. This specification documents the agent-facing capability set (Create Account, Join TCP, View Campaign, Participate, Vote, Redeem Benefits, Verify DE) per the iSHANG AI Communication Plan v1.0, Workstream 2 §4.4 Priority 2. Capabilities not yet implemented are marked `x-status: \"planned\"` — they are design documentation, NOT working endpoints. Contact: noreply@ishang.com.",
    "version": "4.82.0"
  },
  "servers": [
    { "url": "/api", "description": "Trust Network Hub API (same origin)" }
  ],
  "x-agent-capabilities": [
    { "capability": "Create Account", "status": "live", "endpoint": "POST /api/register.php" },
    { "capability": "View Campaign", "status": "live", "endpoint": "GET /api/des-show.php (public storefront) + GET /api/campaigns-mine.php (authenticated listing)" },
    { "capability": "Verify DE", "status": "live", "endpoint": "GET /api/verify-de.php — public, no account required" },
    { "capability": "Participate", "status": "planned", "endpoint": "POST /api/agents/participate (planned)", "note": "Purchase-based participation is live today via POST /api/checkout-create.php. Agent-native participation: Design 2026 · Implementation Q1–Q3 2027 per AI Communication Plan." },
    { "capability": "Join TCP", "status": "planned", "endpoint": "POST /api/agents/join-tcp (planned)", "note": "Design 2026 · Implementation Q1–Q3 2027 per AI Communication Plan." },
    { "capability": "Vote", "status": "planned", "endpoint": "POST /api/agents/vote (planned)", "note": "Design 2026 · Implementation Q1–Q3 2027 per AI Communication Plan." },
    { "capability": "Redeem Benefits", "status": "planned", "endpoint": "POST /api/agents/redeem (planned)", "note": "Design 2026 · Implementation Q1–Q3 2027 per AI Communication Plan." }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": { "type": "http", "scheme": "bearer" }
    },
    "schemas": {
      "User": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "email": { "type": "string", "format": "email" },
          "name": { "type": "string" },
          "role": { "type": "string", "enum": ["member", "organization", "admin"] }
        }
      },
      "AuthResponse": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "token": { "type": "string" },
          "user": { "$ref": "#/components/schemas/User" }
        }
      },
      "Sku": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "sku_code": { "type": "string" },
          "name": { "type": "string" },
          "price_usd_cents": { "type": "integer" },
          "supply": { "type": ["integer", "null"] },
          "sold": { "type": "integer" },
          "remaining": { "type": ["integer", "null"] },
          "terms": { "type": ["string", "null"] }
        }
      },
      "PublicDE": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "de_type": { "type": "string", "description": "One of the 11 canonical DE types" },
          "name": { "type": "string" },
          "description": { "type": ["string", "null"] },
          "campaign_id": { "type": "integer" },
          "campaign_name": { "type": "string" },
          "org_name": { "type": "string" },
          "skus": { "type": "array", "items": { "$ref": "#/components/schemas/Sku" } }
        }
      },
      "Entitlement": {
        "type": "object",
        "properties": {
          "code": { "type": "string", "pattern": "^DE-[0-9A-HJKMNP-TV-Z]{10}$" },
          "status": { "type": "string", "enum": ["active", "used", "revoked"] },
          "issued_at": { "type": "string" },
          "used_at": { "type": ["string", "null"] },
          "terms_snapshot": { "type": ["string", "null"] }
        }
      },
      "CampaignSummary": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "ref": { "type": "string", "example": "CMP-2026-0007" },
          "name": { "type": "string" },
          "framework": { "type": "string" },
          "stage": { "type": ["string", "null"], "description": "Primary lifecycle objective (Join / Participate / Recognized / Steward)" },
          "paid": { "type": "boolean" },
          "status": { "type": "string", "enum": ["draft", "active", "paused", "completed"] },
          "org_name": { "type": "string" },
          "circle_name": { "type": ["string", "null"] },
          "circle_category": { "type": ["string", "null"] },
          "de_count": { "type": "integer" },
          "sku_count": { "type": "integer" },
          "attached_count": { "type": "integer", "description": "DEs reused from the org-wide Trust Circle Program pool" },
          "created_at": { "type": "string" }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean", "example": false },
          "error": { "type": "string" }
        }
      }
    }
  },
  "paths": {
    "/des-show.php": {
      "get": {
        "summary": "View Campaign — public storefront read of one sellable Digital Entitlement",
        "description": "Agent capability: View Campaign (live). Returns an ACTIVE DE under an ACTIVE campaign, with its active SKUs (remaining = supply - sold, null = unlimited). 404 otherwise.",
        "parameters": [
          { "name": "id", "in": "query", "required": true, "schema": { "type": "integer" } }
        ],
        "responses": {
          "200": { "description": "The DE and its SKUs", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "de": { "$ref": "#/components/schemas/PublicDE" } } } } } },
          "404": { "description": "Not found or not active", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/verify-de.php": {
      "get": {
        "summary": "Verify DE — public verification of a Digital Entitlement by code",
        "description": "Agent capability: Verify DE (live). Anyone — participant, provider, or AI agent — can verify an entitlement code (DE-XXXXXXXXXX). Returns valid/invalid plus DE details. Read-only.",
        "parameters": [
          { "name": "code", "in": "query", "required": true, "schema": { "type": "string", "example": "DE-0C3W7X9K2M" } }
        ],
        "responses": {
          "200": {
            "description": "Verification result",
            "content": { "application/json": { "schema": {
              "type": "object",
              "properties": {
                "ok": { "type": "boolean" },
                "valid": { "type": "boolean" },
                "reason": { "type": "string", "enum": ["active", "used", "revoked", "not_found", "invalid_format"] },
                "code": { "type": "string" },
                "de": {
                  "type": "object",
                  "properties": {
                    "name": { "type": "string" },
                    "type": { "type": "string" },
                    "sku": { "type": "string" },
                    "terms": { "type": ["string", "null"] },
                    "campaign": { "type": "string" },
                    "campaign_status": { "type": "string" },
                    "organization": { "type": "string" },
                    "issued_at": { "type": "string" },
                    "used_at": { "type": ["string", "null"] }
                  }
                }
              }
            } } }
          }
        }
      }
    },
    "/checkout-create.php": {
      "post": {
        "summary": "Participate (purchase) — create a checkout session for a DE SKU",
        "description": "Creates an order (ORD-YYYY-NNNN) and a payment checkout session. method='stripe' returns a Stripe Checkout URL; method='coinsbuy' returns a CoinsBuy payment page URL. Redirect the user/agent to checkoutUrl. Entitlements (DE-XXXXXXXXXX codes) are issued after payment confirmation via webhook/callback. Requires payments to be configured on the server (503 otherwise).",
        "security": [{ "bearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["sku_id", "method"],
                "properties": {
                  "sku_id": { "type": "integer", "description": "SKU id from des-show.php" },
                  "qty": { "type": "integer", "minimum": 1, "maximum": 10, "default": 1 },
                  "method": { "type": "string", "enum": ["stripe", "coinsbuy"] }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Checkout session created", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "ref": { "type": "string", "example": "ORD-2026-0007" }, "checkoutUrl": { "type": "string", "format": "uri" } } } } } },
          "400": { "description": "Invalid input or payment method not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "401": { "description": "Missing or expired token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "409": { "description": "SKU not on sale or insufficient supply", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "503": { "description": "Payments not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/campaigns-mine.php": {
      "get": {
        "summary": "List campaigns owned by the authenticated caller",
        "description": "Returns the caller's campaigns with organization and Trust Circle Program (branded circle) names, DE/SKU counts (including reused/attached DEs), status, and lifecycle stage. Ownership is resolved via organizations.owner_user_id.",
        "security": [{ "bearerAuth": [] }],
        "responses": {
          "200": { "description": "The caller's campaigns", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "campaigns": { "type": "array", "items": { "$ref": "#/components/schemas/CampaignSummary" } } } } } } },
          "401": { "description": "Missing or expired token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/order-status.php": {
      "get": {
        "summary": "Poll a single order by public reference",
        "description": "Used by the payment return page after Stripe / CoinsBuy redirects back. The ref must belong to the caller.",
        "security": [{ "bearerAuth": [] }],
        "parameters": [
          { "name": "ref", "in": "query", "required": true, "schema": { "type": "string", "example": "ORD-2026-0007" } }
        ],
        "responses": {
          "200": { "description": "Order with issued entitlements", "content": { "application/json": { "schema": {
            "type": "object",
            "properties": {
              "ok": { "type": "boolean" },
              "order": {
                "type": "object",
                "properties": {
                  "ref": { "type": "string" },
                  "status": { "type": "string", "enum": ["pending", "paid", "canceled", "failed"] },
                  "method": { "type": "string" },
                  "qty": { "type": "integer" },
                  "amount_usd_cents": { "type": "integer" },
                  "sku_name": { "type": "string" },
                  "de_name": { "type": "string" },
                  "de_type": { "type": "string" },
                  "campaign_name": { "type": "string" },
                  "created_at": { "type": "string" },
                  "paid_at": { "type": ["string", "null"] },
                  "entitlements": { "type": "array", "items": { "$ref": "#/components/schemas/Entitlement" } }
                }
              }
            }
          } } } },
          "401": { "description": "Missing or expired token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "404": { "description": "Unknown ref", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/register.php": {
      "post": {
        "summary": "Create Account — register a member account",
        "description": "Agent capability: Create Account (live). Creates a member account and sends a verification email.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email", "password", "name"],
                "properties": {
                  "email": { "type": "string", "format": "email" },
                  "password": { "type": "string", "minLength": 8 },
                  "name": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Account created; verification email sent", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthResponse" } } } },
          "409": { "description": "Email already registered", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/login.php": {
      "post": {
        "summary": "Password sign-in",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email", "password"],
                "properties": {
                  "email": { "type": "string", "format": "email" },
                  "password": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Signed in", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthResponse" } } } },
          "401": { "description": "Invalid credentials", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/request-otp.php": {
      "post": {
        "summary": "Request a one-time passcode (passwordless sign-in)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email"],
                "properties": { "email": { "type": "string", "format": "email" } }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "OTP sent if the account exists", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" } } } } } }
        }
      }
    },
    "/verify-otp.php": {
      "post": {
        "summary": "Verify a one-time passcode and sign in",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email", "code"],
                "properties": {
                  "email": { "type": "string", "format": "email" },
                  "code": { "type": "string", "minLength": 6, "maxLength": 6 }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Signed in", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthResponse" } } } },
          "401": { "description": "Invalid or expired code", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/forgot-password.php": {
      "post": {
        "summary": "Request a password-reset email",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email"],
                "properties": { "email": { "type": "string", "format": "email" } }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Reset email sent if the account exists", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" } } } } } }
        }
      }
    },
    "/reset-password.php": {
      "post": {
        "summary": "Set a new password using a reset token",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["token", "password"],
                "properties": {
                  "token": { "type": "string" },
                  "password": { "type": "string", "minLength": 8 }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Password updated", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" } } } } } },
          "400": { "description": "Invalid or expired token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/verify-email.php": {
      "get": {
        "summary": "Confirm an email address via verification token",
        "parameters": [
          { "name": "token", "in": "query", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Email verified", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" } } } } } }
        }
      }
    },
    "/resend-verification.php": {
      "post": {
        "summary": "Resend the email-verification message",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email"],
                "properties": { "email": { "type": "string", "format": "email" } }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Verification email resent if eligible", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" } } } } } }
        }
      }
    },
    "/me.php": {
      "get": {
        "summary": "Return the authenticated member",
        "security": [{ "bearerAuth": [] }],
        "responses": {
          "200": { "description": "Current user", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "user": { "$ref": "#/components/schemas/User" } } } } } },
          "401": { "description": "Missing or expired token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/logout.php": {
      "post": {
        "summary": "Invalidate the bearer token",
        "security": [{ "bearerAuth": [] }],
        "responses": {
          "200": { "description": "Signed out", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" } } } } } }
        }
      }
    },
    "/agents/register": {
      "post": {
        "x-status": "planned",
        "summary": "Agent Registration — register an agent identity (PLANNED)",
        "description": "PLANNED — NOT IMPLEMENTED. Design 2026 · Implementation Q1–Q3 2027 per AI Communication Plan. Registers an agent in the Agent Registry with: Agent ID, Agent Type (AI / Community / Partner), Agent Owner, Authority Scope, Status (Active / Suspended / Revoked), Trust Score, Relationship Impact. See /agents/onboarding for the design preview.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["agent_type", "owner"],
                "properties": {
                  "agent_type": { "type": "string", "enum": ["ai", "community", "partner"] },
                  "owner": { "type": "string", "description": "Agent Owner — organization or individual operating the agent" },
                  "authority_scope": { "type": "string", "description": "Requested authority scope (maps to authority levels L0–L5)" }
                }
              }
            }
          }
        },
        "responses": {
          "501": { "description": "Not implemented — planned endpoint" }
        }
      }
    },
    "/agents/authorize": {
      "post": {
        "x-status": "planned",
        "summary": "Agent Authorization — obtain an agent credential (PLANNED)",
        "description": "PLANNED — NOT IMPLEMENTED. Design 2026 · Implementation Q1–Q3 2027 per AI Communication Plan. Exchanges a registered Agent ID for an authorized agent credential scoped to the granted authority level.",
        "responses": {
          "501": { "description": "Not implemented — planned endpoint" }
        }
      }
    },
    "/agents/join-tcp": {
      "post": {
        "x-status": "planned",
        "summary": "Join TCP — agent joins a Trust Circle Program (PLANNED)",
        "description": "PLANNED — NOT IMPLEMENTED. Design 2026 · Implementation Q1–Q3 2027 per AI Communication Plan. Agent capability: Join TCP. The agent becomes a participant of a Trust Circle Program, beginning a Trusted Relationship (Organization + Participant + Active Digital Entitlement + Trust Signals + Time).",
        "responses": {
          "501": { "description": "Not implemented — planned endpoint" }
        }
      }
    },
    "/agents/participate": {
      "post": {
        "x-status": "planned",
        "summary": "Participate — agent-native campaign participation (PLANNED)",
        "description": "PLANNED — NOT IMPLEMENTED. Design 2026 · Implementation Q1–Q3 2027 per AI Communication Plan. Agent capability: Participate. Purchase-based participation is LIVE today via POST /checkout-create.php; this endpoint will add agent-native participation (quests, voting, recognition actions) that generates Participation Trust Signals.",
        "responses": {
          "501": { "description": "Not implemented — planned endpoint" }
        }
      }
    },
    "/agents/vote": {
      "post": {
        "x-status": "planned",
        "summary": "Vote — agent voting inside a campaign (PLANNED)",
        "description": "PLANNED — NOT IMPLEMENTED. Design 2026 · Implementation Q1–Q3 2027 per AI Communication Plan. Agent capability: Vote. Voting power derives from held Digital Entitlements and generates Participation / Stewardship Trust Signals.",
        "responses": {
          "501": { "description": "Not implemented — planned endpoint" }
        }
      }
    },
    "/agents/redeem": {
      "post": {
        "x-status": "planned",
        "summary": "Redeem Benefits — redeem a Digital Entitlement (PLANNED)",
        "description": "PLANNED — NOT IMPLEMENTED. Design 2026 · Implementation Q1–Q3 2027 per AI Communication Plan. Agent capability: Redeem Benefits. Redeems an entitlement's benefit per its terms; the DE record is preserved (used, not burned) and generates a Trust Signal.",
        "responses": {
          "501": { "description": "Not implemented — planned endpoint" }
        }
      }
    }
  }
}
