{
  "openapi": "3.1.0",
  "info": {
    "title": "TRI API",
    "version": "1.0.0",
    "description": "TRI API for public identity, public-key discovery, contacts, and secure communication infrastructure. Golden Rule: never expose, store, log, transmit, or reconstruct private keys, seed phrases, backup keys, recovery keys, or decrypted message bodies."
  },
  "servers": [
    {
      "url": "https://api.tri1space.com",
      "description": "TRI staging API"
    }
  ],
  "security": [
    {
      "bearerToken": []
    },
    {
      "triApiKey": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerToken": {
        "type": "http",
        "scheme": "bearer"
      },
      "triApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-TRI-API-Key"
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string"
          }
        },
        "required": [
          "ok",
          "error"
        ]
      },
      "PublicIdentity": {
        "type": "object",
        "properties": {
          "triId": {
            "type": "string"
          },
          "identity": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "handle": {
            "type": "string"
          },
          "bio": {
            "type": "string"
          },
          "avatarUrl": {
            "type": "string"
          },
          "avatarPath": {
            "type": "string"
          },
          "avatarRef": {
            "type": "string"
          },
          "publicKey": {
            "type": "string"
          },
          "edPub": {
            "type": "string"
          },
          "xPub": {
            "type": "string"
          },
          "fingerprint": {
            "type": "string"
          },
          "identityClass": {
            "type": "string"
          },
          "isTestIdentity": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          }
        }
      },
      "ApiKey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "developerName": {
            "type": "string"
          },
          "tokenName": {
            "type": "string"
          },
          "tokenPrefix": {
            "type": "string"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status": {
            "type": "string"
          },
          "createdAt": {
            "type": "string"
          },
          "revokedAt": {
            "type": "string"
          },
          "lastUsedAt": {
            "type": "string"
          }
        }
      }
    }
  },
  "paths": {
    "/health": {
      "get": {
        "security": [],
        "summary": "Service health",
        "responses": {
          "200": {
            "description": "Healthy"
          }
        }
      }
    },
    "/ready": {
      "get": {
        "security": [],
        "summary": "Service readiness",
        "responses": {
          "200": {
            "description": "Ready"
          },
          "503": {
            "description": "Not ready"
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "security": [],
        "summary": "OpenAPI specification",
        "responses": {
          "200": {
            "description": "OpenAPI document"
          }
        }
      }
    },
    "/v1/identity/create": {
      "post": {
        "summary": "Create public identity",
        "description": "Requires identity:write or identity:* scope.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "profile": {
                    "$ref": "#/components/schemas/PublicIdentity"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created public identity"
          },
          "400": {
            "description": "Invalid or sensitive fields rejected",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API token"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/v1/identity/{triId}": {
      "get": {
        "summary": "Get public identity",
        "description": "Requires identity:read or identity:* scope.",
        "parameters": [
          {
            "name": "triId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Public identity"
          },
          "404": {
            "description": "Identity not found"
          }
        }
      }
    },
    "/v1/identity/verify": {
      "post": {
        "summary": "Verify public identity signature material",
        "description": "Requires identity:verify or identity:* scope.",
        "responses": {
          "200": {
            "description": "Verification result"
          },
          "400": {
            "description": "Sensitive fields rejected"
          }
        }
      }
    },
    "/v1/identity/{triId}/public-key": {
      "get": {
        "summary": "Get public key fields",
        "parameters": [
          {
            "name": "triId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Public key fields"
          },
          "404": {
            "description": "Identity not found"
          }
        }
      }
    },
    "/v1/identity/{triId}/status": {
      "get": {
        "summary": "Get identity status",
        "parameters": [
          {
            "name": "triId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Identity status"
          },
          "404": {
            "description": "Identity not found"
          }
        }
      }
    },
    "/api/tri/contacts": {
      "get": {
        "summary": "List contacts",
        "description": "Requires tri:core scope.",
        "responses": {
          "200": {
            "description": "Contacts result"
          }
        }
      }
    },
    "/api/tri/contacts/upsert": {
      "post": {
        "summary": "Create or update contact metadata",
        "description": "Requires tri:core scope.",
        "responses": {
          "200": {
            "description": "Contact upserted"
          },
          "400": {
            "description": "Invalid contact payload"
          }
        }
      }
    },
    "/v1/developer/tokens": {
      "get": {
        "summary": "List API keys",
        "description": "Requires admin:tokens scope.",
        "responses": {
          "200": {
            "description": "API key list"
          }
        }
      },
      "post": {
        "summary": "Create scoped API key",
        "description": "Requires admin:tokens scope. The raw token is returned only once.",
        "responses": {
          "201": {
            "description": "Created API key"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/v1/developer/tokens/{tokenId}/revoke": {
      "post": {
        "summary": "Revoke API key",
        "description": "Requires admin:tokens scope.",
        "parameters": [
          {
            "name": "tokenId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Revoked API key"
          },
          "404": {
            "description": "API key not found"
          }
        }
      }
    },
    "/v1/developer/register": {
      "post": {
        "security": [],
        "summary": "Register developer account",
        "description": "Creates a developer account and returns a developer session token. Does not create TRI API keys automatically.",
        "responses": {
          "201": {
            "description": "Developer registered"
          },
          "400": {
            "description": "Invalid registration payload"
          }
        }
      }
    },
    "/v1/developer/login": {
      "post": {
        "security": [],
        "summary": "Login developer account",
        "responses": {
          "200": {
            "description": "Developer session created"
          },
          "401": {
            "description": "Invalid login"
          }
        }
      }
    },
    "/v1/developer/me": {
      "get": {
        "summary": "Get current developer account",
        "description": "Requires a developer session token from registration or login.",
        "responses": {
          "200": {
            "description": "Developer account"
          },
          "401": {
            "description": "Invalid developer session"
          }
        }
      }
    },
    "/v1/developer/logout": {
      "post": {
        "summary": "Logout developer session",
        "responses": {
          "200": {
            "description": "Developer session revoked"
          },
          "401": {
            "description": "Invalid developer session"
          }
        }
      }
    },
    "/v1/developer/me/tokens": {
      "get": {
        "summary": "List my API keys",
        "description": "Requires a developer session token. Raw API tokens are never returned by list APIs.",
        "responses": {
          "200": {
            "description": "Developer API keys"
          },
          "401": {
            "description": "Invalid developer session"
          }
        }
      },
      "post": {
        "summary": "Create my scoped API key",
        "description": "Requires a developer session token. Raw API token is returned only once. Self-service cannot grant admin:tokens.",
        "responses": {
          "201": {
            "description": "API key created"
          },
          "400": {
            "description": "Invalid scopes"
          },
          "401": {
            "description": "Invalid developer session"
          }
        }
      }
    },
    "/v1/developer/me/tokens/{tokenId}/revoke": {
      "post": {
        "summary": "Revoke my API key",
        "parameters": [
          {
            "name": "tokenId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "API key revoked"
          },
          "404": {
            "description": "API key not found"
          }
        }
      }
    },
    "/v1/developer/me/usage": {
      "get": {
        "summary": "Get my API usage analytics",
        "description": "Usage analytics include method, path, route group, status code, and timestamps only. Request and response bodies are not stored.",
        "responses": {
          "200": {
            "description": "Usage summary"
          },
          "401": {
            "description": "Invalid developer session"
          }
        }
      }
    },
    "/v1/developer/tri1/challenge": {
      "post": {
        "summary": "Create TRI1 developer auth challenge",
        "description": "Starts developer dashboard authentication by issuing a challenge to sign with a TRI1 identity private signing key.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "profile": {
                    "type": "object",
                    "properties": {
                      "identity": {
                        "type": "string"
                      },
                      "triId": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "handle": {
                        "type": "string"
                      },
                      "edPub": {
                        "type": "string"
                      },
                      "xPub": {
                        "type": "string"
                      },
                      "edAlg": {
                        "type": "string"
                      }
                    }
                  }
                },
                "required": [
                  "profile"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Challenge issued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "challengeId": {
                      "type": "string"
                    },
                    "challenge": {
                      "type": "string"
                    },
                    "expiresAt": {
                      "type": "string"
                    },
                    "triId": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid TRI1 profile"
          }
        }
      }
    },
    "/v1/developer/tri1/verify": {
      "post": {
        "summary": "Verify TRI1 developer auth challenge",
        "description": "Verifies a signed TRI1 challenge and returns a developer dashboard session token.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "challengeId": {
                    "type": "string"
                  },
                  "profile": {
                    "type": "object"
                  },
                  "signature": {
                    "type": "string"
                  },
                  "edAlg": {
                    "type": "string"
                  }
                },
                "required": [
                  "challengeId",
                  "profile",
                  "signature"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "TRI1 auth verified and developer session issued"
          },
          "401": {
            "description": "Invalid challenge or signature"
          }
        }
      }
    },
    "/v1/developer/accounts": {
      "get": {
        "summary": "List developer accounts for operator review",
        "description": "Requires admin:tokens scope. Supports optional status filter.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "review",
                "deactivated"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Developer accounts listed"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/v1/developer/accounts/{accountId}/review": {
      "post": {
        "summary": "Mark developer account for review",
        "description": "Requires admin:tokens scope.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Developer account updated"
          },
          "404": {
            "description": "Developer account not found"
          }
        }
      }
    },
    "/v1/developer/accounts/{accountId}/deactivate": {
      "post": {
        "summary": "Deactivate developer account and revoke active API keys",
        "description": "Requires admin:tokens scope.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Developer account updated"
          },
          "404": {
            "description": "Developer account not found"
          }
        }
      }
    },
    "/v1/developer/accounts/{accountId}/reactivate": {
      "post": {
        "summary": "Reactivate developer account",
        "description": "Requires admin:tokens scope.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Developer account updated"
          },
          "404": {
            "description": "Developer account not found"
          }
        }
      }
    }
  }
}
