{
  "openapi": "3.1.0",
  "info": {
    "title": "Amoreg Regulatory Knowledge API",
    "version": "1.0.0",
    "description": "Hybrid semantic + keyword search over Amoreg's regulatory knowledge base, scoped to the jurisdictions enabled for your organisation. Prepaid credits in GBP: 2p per search, 2p per screening keyword."
  },
  "servers": [
    {
      "url": "https://app.amoreg.com/api/v1"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Organisation API key created in the dashboard (format: amrg_live_…). Sent as `Authorization: Bearer amrg_live_…`."
      }
    },
    "schemas": {
      "SearchMatch": {
        "type": "object",
        "properties": {
          "content": {
            "type": "string"
          },
          "score": {
            "type": "number"
          },
          "source": {
            "type": "string"
          },
          "citationPath": {
            "type": "string"
          },
          "jurisdictionSlugs": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "content",
          "score"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "details": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ]
      }
    }
  },
  "paths": {
    "/search": {
      "post": {
        "operationId": "search",
        "summary": "Hybrid search the regulatory knowledge base",
        "description": "Flat 2p per request, debited from your prepaid balance.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "query": {
                    "type": "string",
                    "maxLength": 1000
                  },
                  "jurisdictions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Jurisdiction slugs. Defaults to every jurisdiction enabled for your organisation."
                  },
                  "topK": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 50,
                    "default": 10
                  }
                },
                "required": [
                  "query"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Search results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requestId": {
                      "type": "string"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SearchMatch"
                      }
                    },
                    "creditsChargedPence": {
                      "type": "integer"
                    },
                    "availablePence": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jurisdictions": {
      "get": {
        "operationId": "listJurisdictions",
        "summary": "List jurisdictions available to your organisation",
        "responses": {
          "200": {
            "description": "Available jurisdictions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "jurisdictions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "slug": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/credits": {
      "get": {
        "operationId": "getCredits",
        "summary": "Current prepaid balance",
        "responses": {
          "200": {
            "description": "Balance summary",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "balancePence": {
                      "type": "integer"
                    },
                    "heldPence": {
                      "type": "integer"
                    },
                    "availablePence": {
                      "type": "integer"
                    },
                    "currency": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/credits/ledger": {
      "get": {
        "operationId": "listLedger",
        "summary": "Credit statement (top-ups, reservations, settlements)",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 200
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Ledger entries, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "entries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "top_up",
                              "grant",
                              "reserve",
                              "settle",
                              "release",
                              "adjustment"
                            ]
                          },
                          "amountPence": {
                            "type": "integer"
                          },
                          "currency": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/top-ups": {
      "post": {
        "operationId": "createTopUp",
        "summary": "Create a Revolut checkout for a prepaid top-up",
        "description": "Minimum 1000p (£10). Credits land when the payment completes.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amountPence": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 100000
                  }
                },
                "required": [
                  "amountPence"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Hosted checkout created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "orderId": {
                      "type": "string"
                    },
                    "checkoutUrl": {
                      "type": "string"
                    },
                    "amountPence": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/screenings": {
      "post": {
        "operationId": "createScreening",
        "summary": "Screen a batch of keywords against the knowledge base",
        "description": "Durable background run: reserves 2p per keyword up front, settles the actual cost when the run completes, and releases the remainder. Poll GET /screenings/{id} for results.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "keywords": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 100
                  },
                  "jurisdictions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "topK": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 20,
                    "default": 5
                  }
                },
                "required": [
                  "keywords"
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Screening run accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "estimatedCostPence": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credit for the reservation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/screenings/{id}": {
      "get": {
        "operationId": "getScreening",
        "summary": "Screening run status and results",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Run state; `results` is set once status is completed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "running",
                        "completed",
                        "failed"
                      ]
                    },
                    "keywords": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "jurisdictions": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "keyword": {
                            "type": "string"
                          },
                          "matches": {
                            "type": "array",
                            "items": {
                              "$ref": "#/components/schemas/SearchMatch"
                            }
                          }
                        }
                      }
                    },
                    "error": {
                      "type": "string"
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "completedAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/documents": {
      "get": {
        "operationId": "listDocuments",
        "summary": "List your organisation's policy documents",
        "responses": {
          "200": {
            "description": "Documents",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "documents": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "filename": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "processing",
                              "ready",
                              "failed"
                            ]
                          },
                          "jurisdictionSlugs": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "pages": {
                            "type": "integer",
                            "nullable": true
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "uploadDocument",
        "summary": "Upload a policy PDF into the knowledge base",
        "description": "2p per page (minimum 10p, maximum 500 pages), debited before ingestion. Ingestion runs in the background — poll GET /documents/{id} until the status is ready. A failed ingestion is refunded automatically.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The PDF file."
                  },
                  "jurisdictionSlugs": {
                    "type": "string",
                    "description": "Optional JSON array of jurisdiction slugs, e.g. [\"fca\"]."
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted — ingestion started",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string"
                    },
                    "filename": {
                      "type": "string"
                    },
                    "pages": {
                      "type": "integer"
                    },
                    "creditsChargedPence": {
                      "type": "integer"
                    },
                    "availablePence": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Not a valid PDF / too many pages / bad jurisdictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/documents/{id}": {
      "get": {
        "operationId": "getDocument",
        "summary": "Document status and metadata",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "document": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "filename": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "processing",
                            "ready",
                            "failed"
                          ]
                        },
                        "jurisdictionSlugs": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "pages": {
                          "type": "integer",
                          "nullable": true
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteDocument",
        "summary": "Delete a document from the knowledge base",
        "description": "Removes the document from vector search, file storage, and the database. Ingestion credits are not refunded on delete.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    },
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/executions": {
      "post": {
        "operationId": "createExecution",
        "summary": "Run python code in an isolated sandbox",
        "description": "Durable background run in a fresh Vercel Sandbox. Reserves the worst case up front (5p + 1p per second of the timeout, default 60s, max 300s), settles the actual wall-clock cost when the run completes, and releases the remainder. Poll GET /executions/{id} for output. Execution is at-least-once: an infrastructure retry may run side-effecting code twice.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "maxLength": 65536,
                    "description": "Python source to execute."
                  },
                  "timeoutSeconds": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 300,
                    "default": 60
                  }
                },
                "required": [
                  "code"
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted — execution started",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string"
                    },
                    "estimatedCostPence": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/executions/{id}": {
      "get": {
        "operationId": "getExecution",
        "summary": "Execution run status and output",
        "description": "A non-zero exitCode is still status completed (the code failed, the platform succeeded); status failed means an infrastructure error, which is never charged. stdout/stderr are capped at 64KB each. An exitCode of 124 means the run hit its timeout.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The execution run",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "running",
                        "completed",
                        "failed"
                      ]
                    },
                    "exitCode": {
                      "type": "integer",
                      "nullable": true
                    },
                    "stdout": {
                      "type": "string",
                      "nullable": true
                    },
                    "stderr": {
                      "type": "string",
                      "nullable": true
                    },
                    "durationMs": {
                      "type": "integer",
                      "nullable": true
                    },
                    "error": {
                      "type": "string",
                      "nullable": true
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "completedAt": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  }
}