{
  "openapi": "3.1.0",
  "info": {
    "title": "NoJunk Moderate",
    "version": "1.0.0",
    "description": "Content moderation and text analysis: sentiment, safety classification (14 harm categories), semantic reranking, PII detection and redaction, language detection. Pay per call with USDC on Base (x402). No API key.",
    "x-guidance": "Five endpoints, GET with query parameters or POST with a JSON body, paid per call in USDC on Base via x402 (you are only charged when a valid result is returned; all 4xx/5xx are free). /sentiment {text | texts: [1-50]} -> {label, score, polarity -1..1, results[], summary} costs $0.001 (DistilBERT SST-2). /safety {text | messages: [{role, content}] 1-20} -> {safe, categories: [{code S1-S14, name}], raw} costs $0.002 (Llama Guard 3 8B; categories: violent crimes, non-violent crimes, sex-related crimes, child sexual exploitation, defamation, specialized advice, privacy, intellectual property, indiscriminate weapons, hate, suicide & self-harm, sexual content, elections, code interpreter abuse). /rerank {query, documents: [1-100 strings or {id, text}], top_k?} -> {results: [{rank, id, index, score, text}] best first} costs $0.002 (BGE reranker). /pii {text, redact?, types?} -> {entities: [{type, value, start, end}], redacted?} costs $0.003: email, phone, ssn, credit_card, ip, iban, crypto_address are detected deterministically with regexes (credit cards must pass Luhn, IBANs mod-97); name, address, date_of_birth, passport use Llama 3.3 70B with a JSON schema and are only looked for when requested (default types = all); if the LLM step fails the regex results are still returned with an llm_error field. /language {text | texts: [1-50]} -> {code (ISO 639-1), name, confidence, method} costs $0.001 (Llama 3.3 70B, with a Unicode-script heuristic fallback reported as method \"script\"). Each text is capped at 20000 characters (400 above that) and bodies at 131072 bytes (413). Best for: moderating user-generated content and agent outputs, pre-screening prompts, scrubbing PII before storage or LLM calls, ranking retrieved passages for RAG, routing by language or sentiment."
  },
  "servers": [
    {
      "url": "https://nojunk-moderate.mick8511.workers.dev"
    }
  ],
  "paths": {
    "/sentiment": {
      "get": {
        "operationId": "sentimentGet",
        "summary": "Sentiment (positive/negative, score, polarity) for one text or a batch of up to 50",
        "tags": [
          "Moderation",
          "NLP",
          "AI",
          "sentiment"
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.001000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "parameters": [
          {
            "name": "text",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "One text to analyze (1 to 20000 characters)"
          },
          {
            "name": "texts",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Batch of 1 to 50 texts (use instead of text) (repeat the parameter, pass a JSON array string, or a comma-separated list)"
          }
        ],
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string",
                      "description": "Present when a single `text` was sent"
                    },
                    "score": {
                      "type": "number"
                    },
                    "polarity": {
                      "type": "number"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "index": {
                            "type": "integer"
                          },
                          "label": {
                            "type": "string",
                            "enum": [
                              "positive",
                              "negative"
                            ]
                          },
                          "score": {
                            "type": "number",
                            "description": "Confidence 0-1 of the label"
                          },
                          "polarity": {
                            "type": "number",
                            "minimum": -1,
                            "maximum": 1,
                            "description": "Signed score: positive texts > 0, negative texts < 0"
                          },
                          "chars": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "index",
                          "label",
                          "score",
                          "polarity"
                        ]
                      }
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "count": {
                          "type": "integer"
                        },
                        "positive": {
                          "type": "integer"
                        },
                        "negative": {
                          "type": "integer"
                        },
                        "mean_polarity": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "count",
                        "positive",
                        "negative",
                        "mean_polarity"
                      ]
                    },
                    "model": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Model that produced the result"
                    },
                    "generated_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "results",
                    "summary",
                    "model",
                    "generated_at"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, including any text over 20000 characters (no charge)"
          },
          "402": {
            "description": "Payment Required"
          },
          "413": {
            "description": "Request body larger than 131072 bytes (no charge)"
          },
          "502": {
            "description": "AI model temporarily unavailable or returned an unusable result (no charge)"
          }
        }
      },
      "post": {
        "operationId": "sentimentPost",
        "summary": "Sentiment (positive/negative, score, polarity) for one text or a batch of up to 50",
        "tags": [
          "Moderation",
          "NLP",
          "AI",
          "sentiment"
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.001000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 20000,
                    "description": "One text to analyze (1 to 20000 characters)"
                  },
                  "texts": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 50,
                    "items": {
                      "type": "string",
                      "maxLength": 20000
                    },
                    "description": "Batch of 1 to 50 texts (use instead of text)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string",
                      "description": "Present when a single `text` was sent"
                    },
                    "score": {
                      "type": "number"
                    },
                    "polarity": {
                      "type": "number"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "index": {
                            "type": "integer"
                          },
                          "label": {
                            "type": "string",
                            "enum": [
                              "positive",
                              "negative"
                            ]
                          },
                          "score": {
                            "type": "number",
                            "description": "Confidence 0-1 of the label"
                          },
                          "polarity": {
                            "type": "number",
                            "minimum": -1,
                            "maximum": 1,
                            "description": "Signed score: positive texts > 0, negative texts < 0"
                          },
                          "chars": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "index",
                          "label",
                          "score",
                          "polarity"
                        ]
                      }
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "count": {
                          "type": "integer"
                        },
                        "positive": {
                          "type": "integer"
                        },
                        "negative": {
                          "type": "integer"
                        },
                        "mean_polarity": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "count",
                        "positive",
                        "negative",
                        "mean_polarity"
                      ]
                    },
                    "model": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Model that produced the result"
                    },
                    "generated_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "results",
                    "summary",
                    "model",
                    "generated_at"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, including any text over 20000 characters (no charge)"
          },
          "402": {
            "description": "Payment Required"
          },
          "413": {
            "description": "Request body larger than 131072 bytes (no charge)"
          },
          "502": {
            "description": "AI model temporarily unavailable or returned an unusable result (no charge)"
          }
        }
      }
    },
    "/safety": {
      "get": {
        "operationId": "safetyGet",
        "summary": "Safety classification with Llama Guard 3 (14 hazard categories) for a message or conversation",
        "tags": [
          "Moderation",
          "NLP",
          "AI",
          "safety"
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.002000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "parameters": [
          {
            "name": "text",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "One user message to classify (1 to 20000 characters)"
          },
          {
            "name": "messages",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "A conversation of 1 to 20 {role, content} messages (use instead of text); the last message is classified in context (repeat the parameter, pass a JSON array string, or a comma-separated list)"
          }
        ],
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "safe": {
                      "type": "boolean"
                    },
                    "categories": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string",
                            "enum": [
                              "S1",
                              "S2",
                              "S3",
                              "S4",
                              "S5",
                              "S6",
                              "S7",
                              "S8",
                              "S9",
                              "S10",
                              "S11",
                              "S12",
                              "S13",
                              "S14"
                            ]
                          },
                          "name": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "code",
                          "name"
                        ]
                      },
                      "description": "Violated hazard categories (empty when safe)"
                    },
                    "raw": {
                      "type": "string",
                      "description": "Raw Llama Guard verdict, e.g. 'safe' or 'unsafe\\nS1,S10'"
                    },
                    "messages": {
                      "type": "integer"
                    },
                    "model": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Model that produced the result"
                    },
                    "generated_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "safe",
                    "categories",
                    "raw",
                    "model",
                    "generated_at"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, including any text over 20000 characters (no charge)"
          },
          "402": {
            "description": "Payment Required"
          },
          "413": {
            "description": "Request body larger than 131072 bytes (no charge)"
          },
          "502": {
            "description": "AI model temporarily unavailable or returned an unusable result (no charge)"
          }
        }
      },
      "post": {
        "operationId": "safetyPost",
        "summary": "Safety classification with Llama Guard 3 (14 hazard categories) for a message or conversation",
        "tags": [
          "Moderation",
          "NLP",
          "AI",
          "safety"
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.002000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 20000,
                    "description": "One user message to classify (1 to 20000 characters)"
                  },
                  "messages": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 20,
                    "items": {
                      "type": "object",
                      "properties": {
                        "role": {
                          "type": "string",
                          "enum": [
                            "user",
                            "assistant"
                          ]
                        },
                        "content": {
                          "type": "string",
                          "maxLength": 20000
                        }
                      },
                      "required": [
                        "role",
                        "content"
                      ]
                    },
                    "description": "A conversation of 1 to 20 {role, content} messages (use instead of text); the last message is classified in context"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "safe": {
                      "type": "boolean"
                    },
                    "categories": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string",
                            "enum": [
                              "S1",
                              "S2",
                              "S3",
                              "S4",
                              "S5",
                              "S6",
                              "S7",
                              "S8",
                              "S9",
                              "S10",
                              "S11",
                              "S12",
                              "S13",
                              "S14"
                            ]
                          },
                          "name": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "code",
                          "name"
                        ]
                      },
                      "description": "Violated hazard categories (empty when safe)"
                    },
                    "raw": {
                      "type": "string",
                      "description": "Raw Llama Guard verdict, e.g. 'safe' or 'unsafe\\nS1,S10'"
                    },
                    "messages": {
                      "type": "integer"
                    },
                    "model": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Model that produced the result"
                    },
                    "generated_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "safe",
                    "categories",
                    "raw",
                    "model",
                    "generated_at"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, including any text over 20000 characters (no charge)"
          },
          "402": {
            "description": "Payment Required"
          },
          "413": {
            "description": "Request body larger than 131072 bytes (no charge)"
          },
          "502": {
            "description": "AI model temporarily unavailable or returned an unusable result (no charge)"
          }
        }
      }
    },
    "/rerank": {
      "get": {
        "operationId": "rerankGet",
        "summary": "Semantic reranking of up to 100 documents against a query",
        "tags": [
          "Moderation",
          "NLP",
          "AI",
          "rerank"
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.002000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The search query"
          },
          {
            "name": "documents",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "1 to 100 documents as strings or {id, text} objects (repeat the parameter, pass a JSON array string, or a comma-separated list)"
          },
          {
            "name": "top_k",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Return only the best top_k documents (default all)"
          }
        ],
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": "string"
                    },
                    "results": {
                      "type": "array",
                      "description": "Best first",
                      "items": {
                        "type": "object",
                        "properties": {
                          "rank": {
                            "type": "integer"
                          },
                          "id": {
                            "type": [
                              "string",
                              "integer"
                            ],
                            "description": "Your document id, or its index when none was given"
                          },
                          "index": {
                            "type": "integer",
                            "description": "Position in the submitted documents array"
                          },
                          "score": {
                            "type": "number"
                          },
                          "text": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "rank",
                          "id",
                          "index",
                          "score",
                          "text"
                        ]
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "documents": {
                      "type": "integer"
                    },
                    "model": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Model that produced the result"
                    },
                    "generated_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "query",
                    "results",
                    "count",
                    "documents",
                    "model",
                    "generated_at"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, including any text over 20000 characters (no charge)"
          },
          "402": {
            "description": "Payment Required"
          },
          "413": {
            "description": "Request body larger than 131072 bytes (no charge)"
          },
          "502": {
            "description": "AI model temporarily unavailable or returned an unusable result (no charge)"
          }
        }
      },
      "post": {
        "operationId": "rerankPost",
        "summary": "Semantic reranking of up to 100 documents against a query",
        "tags": [
          "Moderation",
          "NLP",
          "AI",
          "rerank"
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.002000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "query": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "The search query"
                  },
                  "documents": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 100,
                    "items": {
                      "oneOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": [
                                "string",
                                "number"
                              ]
                            },
                            "text": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "text"
                          ]
                        }
                      ]
                    },
                    "description": "1 to 100 documents as strings or {id, text} objects"
                  },
                  "top_k": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "description": "Return only the best top_k documents (default all)"
                  }
                },
                "required": [
                  "query",
                  "documents"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": "string"
                    },
                    "results": {
                      "type": "array",
                      "description": "Best first",
                      "items": {
                        "type": "object",
                        "properties": {
                          "rank": {
                            "type": "integer"
                          },
                          "id": {
                            "type": [
                              "string",
                              "integer"
                            ],
                            "description": "Your document id, or its index when none was given"
                          },
                          "index": {
                            "type": "integer",
                            "description": "Position in the submitted documents array"
                          },
                          "score": {
                            "type": "number"
                          },
                          "text": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "rank",
                          "id",
                          "index",
                          "score",
                          "text"
                        ]
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "documents": {
                      "type": "integer"
                    },
                    "model": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Model that produced the result"
                    },
                    "generated_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "query",
                    "results",
                    "count",
                    "documents",
                    "model",
                    "generated_at"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, including any text over 20000 characters (no charge)"
          },
          "402": {
            "description": "Payment Required"
          },
          "413": {
            "description": "Request body larger than 131072 bytes (no charge)"
          },
          "502": {
            "description": "AI model temporarily unavailable or returned an unusable result (no charge)"
          }
        }
      }
    },
    "/pii": {
      "get": {
        "operationId": "piiGet",
        "summary": "PII detection with offsets (regex + LLM) and optional redaction",
        "tags": [
          "Moderation",
          "NLP",
          "AI",
          "pii"
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.003000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "parameters": [
          {
            "name": "text",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The text to scan (1 to 20000 characters)"
          },
          {
            "name": "redact",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "true also returns `redacted`: the text with each entity replaced by [TYPE]"
          },
          {
            "name": "types",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Subset of types to detect (default all). Regex types: email, phone, ssn, credit_card, ip, iban, crypto_address. LLM types: name, address, date_of_birth, passport (repeat the parameter, pass a JSON array string, or a comma-separated list)"
          }
        ],
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "entities": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": [
                              "email",
                              "phone",
                              "ssn",
                              "credit_card",
                              "ip",
                              "iban",
                              "crypto_address",
                              "name",
                              "address",
                              "date_of_birth",
                              "passport"
                            ]
                          },
                          "value": {
                            "type": "string"
                          },
                          "start": {
                            "type": "integer",
                            "description": "UTF-16 offset in the original text"
                          },
                          "end": {
                            "type": "integer",
                            "description": "Exclusive end offset"
                          }
                        },
                        "required": [
                          "type",
                          "value",
                          "start",
                          "end"
                        ]
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "counts": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "integer"
                      }
                    },
                    "types_checked": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "methods": {
                      "type": "object",
                      "properties": {
                        "regex": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "llm": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "redacted": {
                      "type": "string",
                      "description": "Only when redact=true: the text with each entity replaced by [TYPE]"
                    },
                    "llm_error": {
                      "type": "string",
                      "description": "Present when the LLM step (name/address/date_of_birth/passport) failed; the regex results are still complete and the call is charged"
                    },
                    "model": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Model that produced the result"
                    },
                    "generated_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "entities",
                    "count",
                    "counts",
                    "types_checked",
                    "methods",
                    "model",
                    "generated_at"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, including any text over 20000 characters (no charge)"
          },
          "402": {
            "description": "Payment Required"
          },
          "413": {
            "description": "Request body larger than 131072 bytes (no charge)"
          },
          "502": {
            "description": "AI model temporarily unavailable or returned an unusable result (no charge)"
          }
        }
      },
      "post": {
        "operationId": "piiPost",
        "summary": "PII detection with offsets (regex + LLM) and optional redaction",
        "tags": [
          "Moderation",
          "NLP",
          "AI",
          "pii"
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.003000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 20000,
                    "description": "The text to scan (1 to 20000 characters)"
                  },
                  "redact": {
                    "type": "boolean",
                    "default": false,
                    "description": "true also returns `redacted`: the text with each entity replaced by [TYPE]"
                  },
                  "types": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "email",
                        "phone",
                        "ssn",
                        "credit_card",
                        "ip",
                        "iban",
                        "crypto_address",
                        "name",
                        "address",
                        "date_of_birth",
                        "passport"
                      ]
                    },
                    "description": "Subset of types to detect (default all). Regex types: email, phone, ssn, credit_card, ip, iban, crypto_address. LLM types: name, address, date_of_birth, passport"
                  }
                },
                "required": [
                  "text"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "entities": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": [
                              "email",
                              "phone",
                              "ssn",
                              "credit_card",
                              "ip",
                              "iban",
                              "crypto_address",
                              "name",
                              "address",
                              "date_of_birth",
                              "passport"
                            ]
                          },
                          "value": {
                            "type": "string"
                          },
                          "start": {
                            "type": "integer",
                            "description": "UTF-16 offset in the original text"
                          },
                          "end": {
                            "type": "integer",
                            "description": "Exclusive end offset"
                          }
                        },
                        "required": [
                          "type",
                          "value",
                          "start",
                          "end"
                        ]
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "counts": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "integer"
                      }
                    },
                    "types_checked": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "methods": {
                      "type": "object",
                      "properties": {
                        "regex": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "llm": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "redacted": {
                      "type": "string",
                      "description": "Only when redact=true: the text with each entity replaced by [TYPE]"
                    },
                    "llm_error": {
                      "type": "string",
                      "description": "Present when the LLM step (name/address/date_of_birth/passport) failed; the regex results are still complete and the call is charged"
                    },
                    "model": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Model that produced the result"
                    },
                    "generated_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "entities",
                    "count",
                    "counts",
                    "types_checked",
                    "methods",
                    "model",
                    "generated_at"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, including any text over 20000 characters (no charge)"
          },
          "402": {
            "description": "Payment Required"
          },
          "413": {
            "description": "Request body larger than 131072 bytes (no charge)"
          },
          "502": {
            "description": "AI model temporarily unavailable or returned an unusable result (no charge)"
          }
        }
      }
    },
    "/language": {
      "get": {
        "operationId": "languageGet",
        "summary": "Language identification (ISO 639-1) for one text or a batch of up to 50",
        "tags": [
          "Moderation",
          "NLP",
          "AI",
          "language"
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.001000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "parameters": [
          {
            "name": "text",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "One text to identify (1 to 20000 characters)"
          },
          {
            "name": "texts",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Batch of 1 to 50 texts (use instead of text) (repeat the parameter, pass a JSON array string, or a comma-separated list)"
          }
        ],
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "description": "Present when a single `text` was sent"
                    },
                    "name": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "confidence": {
                      "type": "number"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "index": {
                            "type": "integer"
                          },
                          "code": {
                            "type": "string",
                            "description": "ISO 639-1 code (und = undetermined)"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "confidence": {
                            "type": "number"
                          },
                          "method": {
                            "type": "string",
                            "enum": [
                              "llm",
                              "script"
                            ]
                          },
                          "alternatives": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "code": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "confidence": {
                                  "type": "number"
                                }
                              }
                            }
                          }
                        },
                        "required": [
                          "index",
                          "code",
                          "confidence",
                          "method"
                        ]
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "method": {
                      "type": "string",
                      "enum": [
                        "llm",
                        "script",
                        "mixed"
                      ],
                      "description": "llm = Llama 3.3; script = Unicode-script/stopword heuristic used because the LLM failed"
                    },
                    "llm_error": {
                      "type": "string"
                    },
                    "model": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Model that produced the result"
                    },
                    "generated_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "results",
                    "count",
                    "method",
                    "model",
                    "generated_at"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, including any text over 20000 characters (no charge)"
          },
          "402": {
            "description": "Payment Required"
          },
          "413": {
            "description": "Request body larger than 131072 bytes (no charge)"
          },
          "502": {
            "description": "AI model temporarily unavailable or returned an unusable result (no charge)"
          }
        }
      },
      "post": {
        "operationId": "languagePost",
        "summary": "Language identification (ISO 639-1) for one text or a batch of up to 50",
        "tags": [
          "Moderation",
          "NLP",
          "AI",
          "language"
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.001000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 20000,
                    "description": "One text to identify (1 to 20000 characters)"
                  },
                  "texts": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 50,
                    "items": {
                      "type": "string",
                      "maxLength": 20000
                    },
                    "description": "Batch of 1 to 50 texts (use instead of text)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "description": "Present when a single `text` was sent"
                    },
                    "name": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "confidence": {
                      "type": "number"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "index": {
                            "type": "integer"
                          },
                          "code": {
                            "type": "string",
                            "description": "ISO 639-1 code (und = undetermined)"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "confidence": {
                            "type": "number"
                          },
                          "method": {
                            "type": "string",
                            "enum": [
                              "llm",
                              "script"
                            ]
                          },
                          "alternatives": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "code": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "confidence": {
                                  "type": "number"
                                }
                              }
                            }
                          }
                        },
                        "required": [
                          "index",
                          "code",
                          "confidence",
                          "method"
                        ]
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "method": {
                      "type": "string",
                      "enum": [
                        "llm",
                        "script",
                        "mixed"
                      ],
                      "description": "llm = Llama 3.3; script = Unicode-script/stopword heuristic used because the LLM failed"
                    },
                    "llm_error": {
                      "type": "string"
                    },
                    "model": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Model that produced the result"
                    },
                    "generated_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "results",
                    "count",
                    "method",
                    "model",
                    "generated_at"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, including any text over 20000 characters (no charge)"
          },
          "402": {
            "description": "Payment Required"
          },
          "413": {
            "description": "Request body larger than 131072 bytes (no charge)"
          },
          "502": {
            "description": "AI model temporarily unavailable or returned an unusable result (no charge)"
          }
        }
      }
    }
  }
}