{
  "openapi": "3.0.3",
  "info": {
    "title": "Bindler API",
    "version": "1.0.0",
    "description": "Three regulation calculators as JSON endpoints: EU AI Act classification (Regulation (EU) 2024/1689), CBAM certificate cost 2026 to 2034 (Regulation (EU) 2023/956) and the UAE Corporate Tax computation (Federal Decree-Law No. 47 of 2022). Same code as the free browser tools at bindler.co, generated from them at every build. Free tier: 25 calls a day per IP, no account. Unlimited: $19 a month key from Gumroad. Facts only, the instrument cited in every response; not legal or tax advice. Docs: https://bindler.co/api/",
    "contact": {
      "name": "Bindler",
      "url": "https://bindler.co/api/",
      "email": "bindler540@gmail.com"
    }
  },
  "servers": [
    {
      "url": "https://bindler.co/api/v1"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Gumroad licence key for the product bindler-api, sent in the x-api-key header. Keys that do not match the four-group licence pattern are ignored and the call falls through to the free tier."
      },
      "ApiKeyQuery": {
        "type": "apiKey",
        "in": "query",
        "name": "key",
        "description": "The same Gumroad licence key passed as a query parameter instead of the header, accepted by every endpoint."
      }
    }
  },
  "paths": {
    "/ai-act-classify": {
      "get": {
        "summary": "Classify one AI system under the EU AI Act, query parameters",
        "operationId": "aiActClassifyGet",
        "description": "The same classifier as POST, with every field sent as a query parameter instead of a JSON body. Omitted fields take their defaults.",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": false,
            "description": "Label for the AI system, free text up to 120 characters, echoed back in the input block; it does not change the classification. Default Unnamed system.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "description": "Whether the system is in scope under Article 2: not military or national security only, not research only, not personal non-professional use. Default Yes; No returns Out of scope.",
            "schema": {
              "type": "string",
              "enum": [
                "Yes",
                "No"
              ]
            }
          },
          {
            "name": "role",
            "in": "query",
            "required": false,
            "description": "Your role in the value chain (Article 3), which selects the obligation set: Provider (Article 16), Deployer (Articles 26 and 27), Importer or Distributor (Articles 23 and 24). Default Provider.",
            "schema": {
              "type": "string",
              "enum": [
                "Provider",
                "Deployer",
                "Importer",
                "Distributor"
              ]
            }
          },
          {
            "name": "prohib",
            "in": "query",
            "required": false,
            "description": "The Article 5 prohibited practice the system falls under, such as 5(1)(c) Social scoring; a prefix is enough. Default None. Any practice returns PROHIBITED, banned since 2 February 2025.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "annex",
            "in": "query",
            "required": false,
            "description": "Annex III entry such as 4(a)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "prof",
            "in": "query",
            "required": false,
            "description": "Whether the system performs profiling of natural persons. An Annex III system that profiles is high-risk and cannot rely on the Article 6(3) exemption. Default Yes.",
            "schema": {
              "type": "string",
              "enum": [
                "Yes",
                "No"
              ]
            }
          },
          {
            "name": "ex",
            "in": "query",
            "required": false,
            "description": "Whether the Article 6(3) exemption is claimed: narrow procedural task, improving the result of prior human work, pattern detection without replacing human assessment, or a preparatory task. Default No.",
            "schema": {
              "type": "string",
              "enum": [
                "Yes",
                "No"
              ]
            }
          },
          {
            "name": "a61",
            "in": "query",
            "required": false,
            "description": "Whether the system is a safety component of an Annex I product subject to third-party conformity assessment (Article 6(1)): high-risk, applying from 2 August 2027. Default No.",
            "schema": {
              "type": "string",
              "enum": [
                "Yes",
                "No"
              ]
            }
          },
          {
            "name": "gpai",
            "in": "query",
            "required": false,
            "description": "Whether this is a general-purpose AI model (Article 3(63)), which brings the Article 53 duties and Article 55 where systemic risk is presumed. Default No.",
            "schema": {
              "type": "string",
              "enum": [
                "Yes",
                "No"
              ]
            }
          },
          {
            "name": "a50",
            "in": "query",
            "required": false,
            "description": "Whether an Article 50 transparency case applies: the system interacts with people, generates synthetic audio, image, video or text, does emotion recognition or biometric categorisation, or produces deep fakes. Default No. On its own it returns Limited risk (transparency); on a high-risk system it adds the Article 50 duties to the obligation set.",
            "schema": {
              "type": "string",
              "enum": [
                "Yes",
                "No"
              ]
            }
          },
          {
            "name": "pre",
            "in": "query",
            "required": false,
            "description": "Whether the system was placed on the market before 2 August 2026, which moves the date the duties apply under the Article 111 transitional rules: a high-risk system only on a significant change in design after that date (Article 111(2)), a general-purpose AI model from 2 August 2027 (Article 111(3)). Default No.",
            "schema": {
              "type": "string",
              "enum": [
                "Yes",
                "No"
              ]
            }
          },
          {
            "name": "turnover",
            "in": "query",
            "required": false,
            "description": "Worldwide annual turnover in EUR, optional, used only for the fine ceiling in Article 99, which is the higher of the fixed amount and the percentage of turnover.",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Classification, obligations, applies_from, max_fine_eur, input, basis and docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "The classification result. Every call returns all seven keys.",
                  "properties": {
                    "input": {
                      "type": "object",
                      "description": "The normalised inputs the classification ran on, echoed back. Keys: name, role, scope, gpai, annex, prohib, a61, prof, ex, a50, pre and turn. Yes/No fields are normalised to Yes or No, annex and prohib to a full Annex III or Article 5 entry, and turnover is echoed as the number turn.",
                      "properties": {},
                      "additionalProperties": true
                    },
                    "classification": {
                      "type": "string",
                      "description": "The risk class the Regulation puts the system in.",
                      "enum": [
                        "Out of scope",
                        "PROHIBITED (Article 5)",
                        "High-risk",
                        "General-purpose AI model",
                        "Limited risk (transparency)",
                        "Minimal risk"
                      ]
                    },
                    "obligations": {
                      "type": "string",
                      "description": "The duties that follow from the class, with the article numbers, as one semicolon-separated sentence."
                    },
                    "applies_from": {
                      "type": "string",
                      "description": "The date those duties start to apply for this system: 2 February 2025 for a prohibited practice, 2 August 2025 or 2 August 2027 for a general-purpose model, 2 August 2026 or 2 August 2027 for high-risk, the Article 111(2) significant-change wording for a system on the market before 2 August 2026, or n/a when out of scope."
                    },
                    "max_fine_eur": {
                      "type": "number",
                      "description": "The Article 99 ceiling in EUR: the higher of the fixed amount (35 million for a prohibited practice, 15 million otherwise) and the percentage of worldwide turnover (7 percent or 3 percent). Zero where no fine attaches, that is out of scope and minimal risk."
                    },
                    "basis": {
                      "type": "string",
                      "description": "The instrument and articles the answer rests on, with the note that it is not legal advice."
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the documentation section for this endpoint, https://bindler.co/api/#ai-act-classify"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request: the body was not valid JSON, or annex or prohib was sent with a value that matches no entry. The allowed list is returned with the error in the second case.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned for an unusable request.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "What was wrong: send JSON or query parameters, or that annex or prohib must be one of the listed entries."
                    },
                    "allowed": {
                      "type": "array",
                      "description": "Every accepted value for the field that failed, the Annex III entries for annex or the Article 5 practices for prohib. Present only on that error.",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key: a value shaped like a Gumroad licence key was sent in x-api-key or ?key= and Gumroad did not verify it (refunded, charged back or cancelled purchases count as invalid).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned when the presented licence key does not verify.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Always the text invalid key.",
                      "enum": [
                        "invalid key"
                      ]
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the API documentation page, https://bindler.co/api/"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Free tier exhausted: more than 25 active minutes of calls from this IP in the current UTC day, and no verified key was sent. Send a key to remove the limit.",
            "headers": {
              "x-ratelimit-limit": {
                "description": "The free tier ceiling, the string 25.",
                "schema": {
                  "type": "string"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Remaining free calls, the string 0 on this response.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned when the free per-IP allowance is spent.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Explains the free tier ceiling and how to send a key."
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the API documentation page, https://bindler.co/api/"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Classify one AI system under the EU AI Act",
        "operationId": "aiActClassify",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "Label for the AI system, free text up to 120 characters, echoed back in the input block; it does not change the classification. Default Unnamed system.",
                    "type": "string"
                  },
                  "scope": {
                    "description": "Whether the system is in scope under Article 2: not military or national security only, not research only, not personal non-professional use. Default Yes; No returns Out of scope.",
                    "type": "string",
                    "enum": [
                      "Yes",
                      "No"
                    ]
                  },
                  "role": {
                    "description": "Your role in the value chain (Article 3), which selects the obligation set: Provider (Article 16), Deployer (Articles 26 and 27), Importer or Distributor (Articles 23 and 24). Default Provider.",
                    "type": "string",
                    "enum": [
                      "Provider",
                      "Deployer",
                      "Importer",
                      "Distributor"
                    ]
                  },
                  "prohib": {
                    "description": "The Article 5 prohibited practice the system falls under, such as 5(1)(c) Social scoring; a prefix is enough. Default None. Any practice returns PROHIBITED, banned since 2 February 2025.",
                    "type": "string"
                  },
                  "annex": {
                    "type": "string",
                    "description": "Annex III entry such as 4(a)"
                  },
                  "prof": {
                    "description": "Whether the system performs profiling of natural persons. An Annex III system that profiles is high-risk and cannot rely on the Article 6(3) exemption. Default Yes.",
                    "type": "string",
                    "enum": [
                      "Yes",
                      "No"
                    ]
                  },
                  "ex": {
                    "description": "Whether the Article 6(3) exemption is claimed: narrow procedural task, improving the result of prior human work, pattern detection without replacing human assessment, or a preparatory task. Default No.",
                    "type": "string",
                    "enum": [
                      "Yes",
                      "No"
                    ]
                  },
                  "a61": {
                    "description": "Whether the system is a safety component of an Annex I product subject to third-party conformity assessment (Article 6(1)): high-risk, applying from 2 August 2027. Default No.",
                    "type": "string",
                    "enum": [
                      "Yes",
                      "No"
                    ]
                  },
                  "gpai": {
                    "description": "Whether this is a general-purpose AI model (Article 3(63)), which brings the Article 53 duties and Article 55 where systemic risk is presumed. Default No.",
                    "type": "string",
                    "enum": [
                      "Yes",
                      "No"
                    ]
                  },
                  "a50": {
                    "description": "Whether an Article 50 transparency case applies: the system interacts with people, generates synthetic audio, image, video or text, does emotion recognition or biometric categorisation, or produces deep fakes. Default No. On its own it returns Limited risk (transparency); on a high-risk system it adds the Article 50 duties to the obligation set.",
                    "type": "string",
                    "enum": [
                      "Yes",
                      "No"
                    ]
                  },
                  "pre": {
                    "description": "Whether the system was placed on the market before 2 August 2026, which moves the date the duties apply under the Article 111 transitional rules: a high-risk system only on a significant change in design after that date (Article 111(2)), a general-purpose AI model from 2 August 2027 (Article 111(3)). Default No.",
                    "type": "string",
                    "enum": [
                      "Yes",
                      "No"
                    ]
                  },
                  "turnover": {
                    "description": "Worldwide annual turnover in EUR, optional, used only for the fine ceiling in Article 99, which is the higher of the fixed amount and the percentage of turnover.",
                    "type": "number"
                  }
                }
              },
              "example": {
                "name": "CV screening",
                "role": "Provider",
                "annex": "4(a)",
                "turnover": 50000000
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Classification, obligations, applies_from, max_fine_eur, input, basis and docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "The classification result. Every call returns all seven keys.",
                  "properties": {
                    "input": {
                      "type": "object",
                      "description": "The normalised inputs the classification ran on, echoed back. Keys: name, role, scope, gpai, annex, prohib, a61, prof, ex, a50, pre and turn. Yes/No fields are normalised to Yes or No, annex and prohib to a full Annex III or Article 5 entry, and turnover is echoed as the number turn.",
                      "properties": {},
                      "additionalProperties": true
                    },
                    "classification": {
                      "type": "string",
                      "description": "The risk class the Regulation puts the system in.",
                      "enum": [
                        "Out of scope",
                        "PROHIBITED (Article 5)",
                        "High-risk",
                        "General-purpose AI model",
                        "Limited risk (transparency)",
                        "Minimal risk"
                      ]
                    },
                    "obligations": {
                      "type": "string",
                      "description": "The duties that follow from the class, with the article numbers, as one semicolon-separated sentence."
                    },
                    "applies_from": {
                      "type": "string",
                      "description": "The date those duties start to apply for this system: 2 February 2025 for a prohibited practice, 2 August 2025 or 2 August 2027 for a general-purpose model, 2 August 2026 or 2 August 2027 for high-risk, the Article 111(2) significant-change wording for a system on the market before 2 August 2026, or n/a when out of scope."
                    },
                    "max_fine_eur": {
                      "type": "number",
                      "description": "The Article 99 ceiling in EUR: the higher of the fixed amount (35 million for a prohibited practice, 15 million otherwise) and the percentage of worldwide turnover (7 percent or 3 percent). Zero where no fine attaches, that is out of scope and minimal risk."
                    },
                    "basis": {
                      "type": "string",
                      "description": "The instrument and articles the answer rests on, with the note that it is not legal advice."
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the documentation section for this endpoint, https://bindler.co/api/#ai-act-classify"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request: the body was not valid JSON, or annex or prohib was sent with a value that matches no entry. The allowed list is returned with the error in the second case.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned for an unusable request.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "What was wrong: send JSON or query parameters, or that annex or prohib must be one of the listed entries."
                    },
                    "allowed": {
                      "type": "array",
                      "description": "Every accepted value for the field that failed, the Annex III entries for annex or the Article 5 practices for prohib. Present only on that error.",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key: a value shaped like a Gumroad licence key was sent in x-api-key or ?key= and Gumroad did not verify it (refunded, charged back or cancelled purchases count as invalid).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned when the presented licence key does not verify.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Always the text invalid key.",
                      "enum": [
                        "invalid key"
                      ]
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the API documentation page, https://bindler.co/api/"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Free tier exhausted: more than 25 active minutes of calls from this IP in the current UTC day, and no verified key was sent. Send a key to remove the limit.",
            "headers": {
              "x-ratelimit-limit": {
                "description": "The free tier ceiling, the string 25.",
                "schema": {
                  "type": "string"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Remaining free calls, the string 0 on this response.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned when the free per-IP allowance is spent.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Explains the free tier ceiling and how to send a key."
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the API documentation page, https://bindler.co/api/"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "options": {
        "summary": "CORS preflight for the AI Act endpoint",
        "operationId": "aiActClassifyOptions",
        "description": "Answers the browser preflight with the allowed origin, methods and headers, and no body.",
        "security": [],
        "responses": {
          "204": {
            "description": "CORS preflight answered with no body. The endpoint replies to OPTIONS before any key check or rate limiting.",
            "headers": {
              "access-control-allow-origin": {
                "description": "Always the wildcard star, any origin may call.",
                "schema": {
                  "type": "string"
                }
              },
              "access-control-allow-methods": {
                "description": "The methods allowed, the string GET, POST, OPTIONS.",
                "schema": {
                  "type": "string"
                }
              },
              "access-control-allow-headers": {
                "description": "The headers allowed, content-type and x-api-key.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/cbam-cost": {
      "get": {
        "summary": "CBAM certificate cost, query parameters",
        "operationId": "cbamCostGet",
        "description": "The same calculation as POST, with the basket passed as a JSON string in the lines query parameter.",
        "parameters": [
          {
            "name": "year",
            "in": "query",
            "required": false,
            "description": "Year of import, 2026 to 2034. It sets the CBAM factor, the complement of the free allocation share (Directive (EU) 2023/959, Article 10a(1a)). Default 2026.",
            "schema": {
              "type": "integer",
              "minimum": 2026,
              "maximum": 2034
            }
          },
          {
            "name": "price",
            "in": "query",
            "required": false,
            "description": "certificate price, EUR per tCO2e",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "lines",
            "in": "query",
            "required": true,
            "description": "The import basket as a JSON array in a single string, the same objects the POST body takes, url-encoded. The endpoint parses the string; anything that does not parse to a non-empty array returns 400.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The priced basket: totals, certificates, cost, the per-line detail, the same basket in every year, basis and docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "The priced basket. Every call returns all fourteen keys.",
                  "properties": {
                    "year": {
                      "type": "integer",
                      "description": "The year the basket was priced in, as used, default 2026."
                    },
                    "certificate_price_eur": {
                      "type": "number",
                      "description": "The certificate price used, in EUR per tCO2e, as sent, default zero."
                    },
                    "cbam_factor": {
                      "type": "number",
                      "description": "The CBAM factor applied for that year, the complement of the free allocation share."
                    },
                    "tonnes": {
                      "type": "number",
                      "description": "Total tonnes of goods across the basket, tested against the 50 tonne threshold."
                    },
                    "embedded_tco2e": {
                      "type": "number",
                      "description": "Total embedded emissions of the basket before the CBAM factor."
                    },
                    "chargeable_tco2e": {
                      "type": "number",
                      "description": "Total emissions after the CBAM factor, the chargeable quantity."
                    },
                    "certificates": {
                      "type": "integer",
                      "description": "Certificates to surrender, the chargeable tonnes rounded up to the next whole certificate."
                    },
                    "cost_eur": {
                      "type": "number",
                      "description": "Total cost of the basket in EUR at the certificate price given."
                    },
                    "cost_per_tonne_eur": {
                      "type": "number",
                      "description": "Cost divided by tonnes of goods, zero when the basket has no tonnage."
                    },
                    "above_50t_threshold": {
                      "type": "boolean",
                      "description": "Whether total tonnes exceed 50, the single mass threshold below which there is no CBAM obligation."
                    },
                    "lines": {
                      "type": "array",
                      "description": "One entry per goods line sent, in order, at most the first 200.",
                      "items": {
                        "type": "object",
                        "description": "One priced goods line, in the order it was sent.",
                        "properties": {
                          "sector": {
                            "type": "string",
                            "description": "The Annex I goods group used for the line, after matching; an unrecognised sector falls back to Iron and steel.",
                            "enum": [
                              "Cement",
                              "Fertilisers",
                              "Iron and steel",
                              "Aluminium",
                              "Hydrogen",
                              "Electricity"
                            ]
                          },
                          "cn": {
                            "type": "string",
                            "description": "The CN code as sent, echoed back unchanged."
                          },
                          "origin": {
                            "type": "string",
                            "description": "The country of origin as sent, echoed back unchanged."
                          },
                          "tonnes": {
                            "type": "number",
                            "description": "Quantity of goods on this line, in tonnes, as sent."
                          },
                          "indirect_counted": {
                            "type": "boolean",
                            "description": "Whether indirect emissions count for this sector, true for Cement and Fertilisers only, per Annex II."
                          },
                          "embedded_tco2e": {
                            "type": "number",
                            "description": "Total embedded emissions of the line, tonnes multiplied by embedded_per_tonne."
                          },
                          "chargeable_tco2e": {
                            "type": "number",
                            "description": "Embedded emissions of the line after the CBAM factor for the year is applied."
                          },
                          "net_price_eur": {
                            "type": "number",
                            "description": "Certificate price less any carbon price already paid in the country of origin, floored at zero."
                          },
                          "cost_eur": {
                            "type": "number",
                            "description": "Cost of the line, chargeable_tco2e multiplied by net_price_eur."
                          }
                        }
                      }
                    },
                    "same_basket_every_year": {
                      "type": "array",
                      "description": "The same basket priced in each year from 2026 to 2034 at the same certificate price.",
                      "items": {
                        "type": "object",
                        "description": "The same basket priced in one of the nine years.",
                        "properties": {
                          "year": {
                            "type": "integer",
                            "description": "The year of import, 2026 through 2034."
                          },
                          "cbam_factor": {
                            "type": "number",
                            "description": "The CBAM factor for that year, 0.025 in 2026 rising to 1.0 in 2034."
                          },
                          "chargeable_tco2e": {
                            "type": "number",
                            "description": "Basket emissions after that year's factor."
                          },
                          "certificates": {
                            "type": "integer",
                            "description": "Certificates to surrender that year, the chargeable tonnes rounded up."
                          },
                          "cost_eur": {
                            "type": "number",
                            "description": "Basket cost in that year at the same certificate price."
                          }
                        }
                      }
                    },
                    "basis": {
                      "type": "string",
                      "description": "The instruments the calculation rests on, with the note that it is not advice."
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the documentation section for this endpoint, https://bindler.co/api/#cbam-cost"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request: the body was not valid JSON, the year is outside 2026 to 2034, or lines is missing, not an array or empty. The sector list is returned with the error in the last case.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned for an unusable request.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "What was wrong: send JSON, the year range, or the shape lines must take."
                    },
                    "sectors": {
                      "type": "array",
                      "description": "The six accepted sector names. Present only on the lines error.",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key: a value shaped like a Gumroad licence key was sent in x-api-key or ?key= and Gumroad did not verify it (refunded, charged back or cancelled purchases count as invalid).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned when the presented licence key does not verify.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Always the text invalid key.",
                      "enum": [
                        "invalid key"
                      ]
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the API documentation page, https://bindler.co/api/"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Free tier exhausted: more than 25 active minutes of calls from this IP in the current UTC day, and no verified key was sent. Send a key to remove the limit.",
            "headers": {
              "x-ratelimit-limit": {
                "description": "The free tier ceiling, the string 25.",
                "schema": {
                  "type": "string"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Remaining free calls, the string 0 on this response.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned when the free per-IP allowance is spent.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Explains the free tier ceiling and how to send a key."
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the API documentation page, https://bindler.co/api/"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "CBAM certificate cost for a basket of goods, 2026 to 2034",
        "operationId": "cbamCost",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "year": {
                    "description": "Year of import, 2026 to 2034. It sets the CBAM factor, the complement of the free allocation share (Directive (EU) 2023/959, Article 10a(1a)). Default 2026.",
                    "type": "integer",
                    "minimum": 2026,
                    "maximum": 2034
                  },
                  "price": {
                    "type": "number",
                    "description": "certificate price, EUR per tCO2e"
                  },
                  "lines": {
                    "description": "The import basket: one object per goods line, at least one and at most 200.",
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "sector": {
                          "description": "Annex I goods group for the line. Cement and Fertilisers count indirect emissions as well as direct; Iron and steel, Aluminium and Hydrogen count direct emissions only (Annex II); Electricity is priced on its own generation emissions. Default Iron and steel.",
                          "type": "string",
                          "enum": [
                            "Cement",
                            "Fertilisers",
                            "Iron and steel",
                            "Aluminium",
                            "Hydrogen",
                            "Electricity"
                          ]
                        },
                        "cn": {
                          "description": "CN code of the goods, such as 7208. Returned on the line; it does not change the calculation.",
                          "type": "string"
                        },
                        "origin": {
                          "description": "Country of origin of the goods, such as TR. Returned on the line; it does not change the calculation.",
                          "type": "string"
                        },
                        "tonnes": {
                          "description": "Quantity imported on this line, in tonnes of goods. The basket total is tested against the 50 tonne single mass threshold, below which there is no CBAM obligation.",
                          "type": "number"
                        },
                        "embedded_per_tonne": {
                          "description": "Embedded emissions in tCO2e per tonne of goods, direct plus indirect where Annex II counts indirect. Use the producer's verified actual values, or the Commission default for the CN code and country.",
                          "type": "number"
                        },
                        "origin_carbon_price_eur_per_t": {
                          "description": "Carbon price already paid in the country of origin, EUR per tonne of CO2e, netted off the certificate price for this line and floored at zero (Article 9).",
                          "type": "number"
                        }
                      }
                    },
                    "minItems": 1,
                    "maxItems": 200
                  }
                }
              },
              "example": {
                "year": 2026,
                "price": 80,
                "lines": [
                  {
                    "sector": "Iron and steel",
                    "cn": "7208",
                    "origin": "TR",
                    "tonnes": 1000,
                    "embedded_per_tonne": 1.9,
                    "origin_carbon_price_eur_per_t": 0
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The priced basket: totals, certificates, cost, the per-line detail, the same basket in every year, basis and docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "The priced basket. Every call returns all fourteen keys.",
                  "properties": {
                    "year": {
                      "type": "integer",
                      "description": "The year the basket was priced in, as used, default 2026."
                    },
                    "certificate_price_eur": {
                      "type": "number",
                      "description": "The certificate price used, in EUR per tCO2e, as sent, default zero."
                    },
                    "cbam_factor": {
                      "type": "number",
                      "description": "The CBAM factor applied for that year, the complement of the free allocation share."
                    },
                    "tonnes": {
                      "type": "number",
                      "description": "Total tonnes of goods across the basket, tested against the 50 tonne threshold."
                    },
                    "embedded_tco2e": {
                      "type": "number",
                      "description": "Total embedded emissions of the basket before the CBAM factor."
                    },
                    "chargeable_tco2e": {
                      "type": "number",
                      "description": "Total emissions after the CBAM factor, the chargeable quantity."
                    },
                    "certificates": {
                      "type": "integer",
                      "description": "Certificates to surrender, the chargeable tonnes rounded up to the next whole certificate."
                    },
                    "cost_eur": {
                      "type": "number",
                      "description": "Total cost of the basket in EUR at the certificate price given."
                    },
                    "cost_per_tonne_eur": {
                      "type": "number",
                      "description": "Cost divided by tonnes of goods, zero when the basket has no tonnage."
                    },
                    "above_50t_threshold": {
                      "type": "boolean",
                      "description": "Whether total tonnes exceed 50, the single mass threshold below which there is no CBAM obligation."
                    },
                    "lines": {
                      "type": "array",
                      "description": "One entry per goods line sent, in order, at most the first 200.",
                      "items": {
                        "type": "object",
                        "description": "One priced goods line, in the order it was sent.",
                        "properties": {
                          "sector": {
                            "type": "string",
                            "description": "The Annex I goods group used for the line, after matching; an unrecognised sector falls back to Iron and steel.",
                            "enum": [
                              "Cement",
                              "Fertilisers",
                              "Iron and steel",
                              "Aluminium",
                              "Hydrogen",
                              "Electricity"
                            ]
                          },
                          "cn": {
                            "type": "string",
                            "description": "The CN code as sent, echoed back unchanged."
                          },
                          "origin": {
                            "type": "string",
                            "description": "The country of origin as sent, echoed back unchanged."
                          },
                          "tonnes": {
                            "type": "number",
                            "description": "Quantity of goods on this line, in tonnes, as sent."
                          },
                          "indirect_counted": {
                            "type": "boolean",
                            "description": "Whether indirect emissions count for this sector, true for Cement and Fertilisers only, per Annex II."
                          },
                          "embedded_tco2e": {
                            "type": "number",
                            "description": "Total embedded emissions of the line, tonnes multiplied by embedded_per_tonne."
                          },
                          "chargeable_tco2e": {
                            "type": "number",
                            "description": "Embedded emissions of the line after the CBAM factor for the year is applied."
                          },
                          "net_price_eur": {
                            "type": "number",
                            "description": "Certificate price less any carbon price already paid in the country of origin, floored at zero."
                          },
                          "cost_eur": {
                            "type": "number",
                            "description": "Cost of the line, chargeable_tco2e multiplied by net_price_eur."
                          }
                        }
                      }
                    },
                    "same_basket_every_year": {
                      "type": "array",
                      "description": "The same basket priced in each year from 2026 to 2034 at the same certificate price.",
                      "items": {
                        "type": "object",
                        "description": "The same basket priced in one of the nine years.",
                        "properties": {
                          "year": {
                            "type": "integer",
                            "description": "The year of import, 2026 through 2034."
                          },
                          "cbam_factor": {
                            "type": "number",
                            "description": "The CBAM factor for that year, 0.025 in 2026 rising to 1.0 in 2034."
                          },
                          "chargeable_tco2e": {
                            "type": "number",
                            "description": "Basket emissions after that year's factor."
                          },
                          "certificates": {
                            "type": "integer",
                            "description": "Certificates to surrender that year, the chargeable tonnes rounded up."
                          },
                          "cost_eur": {
                            "type": "number",
                            "description": "Basket cost in that year at the same certificate price."
                          }
                        }
                      }
                    },
                    "basis": {
                      "type": "string",
                      "description": "The instruments the calculation rests on, with the note that it is not advice."
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the documentation section for this endpoint, https://bindler.co/api/#cbam-cost"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request: the body was not valid JSON, the year is outside 2026 to 2034, or lines is missing, not an array or empty. The sector list is returned with the error in the last case.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned for an unusable request.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "What was wrong: send JSON, the year range, or the shape lines must take."
                    },
                    "sectors": {
                      "type": "array",
                      "description": "The six accepted sector names. Present only on the lines error.",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key: a value shaped like a Gumroad licence key was sent in x-api-key or ?key= and Gumroad did not verify it (refunded, charged back or cancelled purchases count as invalid).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned when the presented licence key does not verify.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Always the text invalid key.",
                      "enum": [
                        "invalid key"
                      ]
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the API documentation page, https://bindler.co/api/"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Free tier exhausted: more than 25 active minutes of calls from this IP in the current UTC day, and no verified key was sent. Send a key to remove the limit.",
            "headers": {
              "x-ratelimit-limit": {
                "description": "The free tier ceiling, the string 25.",
                "schema": {
                  "type": "string"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Remaining free calls, the string 0 on this response.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned when the free per-IP allowance is spent.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Explains the free tier ceiling and how to send a key."
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the API documentation page, https://bindler.co/api/"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "options": {
        "summary": "CORS preflight for the CBAM endpoint",
        "operationId": "cbamCostOptions",
        "description": "Answers the browser preflight with the allowed origin, methods and headers, and no body.",
        "security": [],
        "responses": {
          "204": {
            "description": "CORS preflight answered with no body. The endpoint replies to OPTIONS before any key check or rate limiting.",
            "headers": {
              "access-control-allow-origin": {
                "description": "Always the wildcard star, any origin may call.",
                "schema": {
                  "type": "string"
                }
              },
              "access-control-allow-methods": {
                "description": "The methods allowed, the string GET, POST, OPTIONS.",
                "schema": {
                  "type": "string"
                }
              },
              "access-control-allow-headers": {
                "description": "The headers allowed, content-type and x-api-key.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/uae-corporate-tax": {
      "get": {
        "summary": "UAE Corporate Tax computation for one Tax Period",
        "operationId": "uaeCorporateTax",
        "parameters": [
          {
            "name": "rev",
            "in": "query",
            "description": "Revenue for the Tax Period in AED, gross income and not profit (Article 21 and Ministerial Decision 73 of 2023 Article 2(4)); tested against the AED 3,000,000 Small Business Relief threshold.",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "acc",
            "in": "query",
            "description": "Accounting Income in AED: the net profit or loss before tax that starts the computation (Article 20(2)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "ie",
            "in": "query",
            "description": "Interest expenditure for the period in AED (Article 29). Feeds Net Interest Expenditure and the EBITDA of the interest limitation (Article 30(1)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "ii",
            "in": "query",
            "description": "Interest income for the period in AED, netted against interest expenditure in Net Interest Expenditure and in EBITDA (Article 30(1) and 30(2)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "da",
            "in": "query",
            "description": "Depreciation and amortisation charged in the period in AED, added back in the EBITDA used for the interest limitation (Article 30(1)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "div",
            "in": "query",
            "description": "Dividends and profit distributions from UAE resident juridical persons in AED, exempt without conditions (Article 22(1)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "part",
            "in": "query",
            "description": "Participation Exemption income in AED: dividends and gains from a Participating Interest, exempt where the conditions of Article 23 are met. Deducted from Accounting Income and from the EBITDA used for the interest limitation (Article 30(1)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "oex",
            "in": "query",
            "description": "Other exempt income in AED under Articles 22 and 24, such as income of a Foreign Permanent Establishment where that exemption applies (Article 24). Deducted from Accounting Income and from the EBITDA used for the interest limitation.",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "ent",
            "in": "query",
            "description": "Entertainment, amusement or recreation expenditure in AED; 50% is added back as non-deductible (Article 32(1)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "fines",
            "in": "query",
            "description": "Fines and penalties other than compensation for damages in AED, added back in full (Article 33(2)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "don",
            "in": "query",
            "description": "Donations, grants or gifts to entities that are not Qualifying Public Benefit Entities in AED, added back in full (Article 33(1)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "dvo",
            "in": "query",
            "description": "Dividends or other profit distributions to an owner that were charged to income in AED, added back in full as non-deductible (Article 33(4)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "ctx",
            "in": "query",
            "description": "Corporate Tax expense booked in the accounts in AED, added back in full because the tax itself is not a deductible expenditure (Article 33(6)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "vat",
            "in": "query",
            "description": "Recoverable input VAT charged to expense in AED, added back in full as non-deductible (Article 33(7)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "ftx",
            "in": "query",
            "description": "Foreign income tax charged to expense in AED, added back in full as non-deductible (Article 33(8)); relief for foreign tax comes through the Foreign Tax Credit line instead (Article 47).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "nb",
            "in": "query",
            "description": "Expenditure not incurred for the purposes of the Business in AED, added back as non-deductible (Article 28(2)(a)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "exx",
            "in": "query",
            "description": "Expenditure incurred in deriving Exempt Income in AED, added back as non-deductible together with the expenditure not incurred for the purposes of the Business (Article 28(2)(b)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "loss",
            "in": "query",
            "description": "Tax Losses carried forward from earlier Tax Periods in AED. Relief is capped at 75% of Taxable Income before relief (Article 37(2)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "icf",
            "in": "query",
            "description": "Disallowed Net Interest Expenditure brought forward from earlier periods in AED, deductible within the same 30% of EBITDA cap for ten periods (Article 30(4)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "ftc",
            "in": "query",
            "description": "Foreign Tax Credit available for the period in AED (Article 47), deducted from the Corporate Tax before credit and capped at it, so it cannot create a refund or a carry-forward (Article 47(2) and 47(3)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "qi",
            "in": "query",
            "description": "Qualifying Income of a Qualifying Free Zone Person in AED (Cabinet Decision No. 55 of 2023). Used only where the QFZP tests pass: 0% on this figure and 9% on Taxable Income above it (Article 3(2)).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "nqr",
            "in": "query",
            "description": "Non-qualifying Revenue in AED, tested for the Free Zone de minimis rule: it must not exceed the lower of 5% of Revenue and AED 5,000,000, or Qualifying Free Zone Person status fails and the standard rates apply to everything (Ministerial Decision No. 139 of 2023, Article 4).",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "resident",
            "in": "query",
            "description": "Whether the taxpayer is a Resident Person (Article 11). Small Business Relief is available to Resident Persons only (Ministerial Decision 73 of 2023 Article 2). Default Yes.",
            "schema": {
              "type": "string",
              "enum": [
                "Yes",
                "No"
              ]
            }
          },
          {
            "name": "fz",
            "in": "query",
            "description": "Whether the taxpayer is a Free Zone Person (Article 18). Default No.",
            "schema": {
              "type": "string",
              "enum": [
                "Yes",
                "No"
              ]
            }
          },
          {
            "name": "qf",
            "in": "query",
            "description": "Whether every Qualifying Free Zone Person condition is met: substance, audited accounts, transfer pricing and no election out (Article 18(1)). With the de minimis test passed, the QFZP rates in Article 3(2) apply. Default No.",
            "schema": {
              "type": "string",
              "enum": [
                "Yes",
                "No"
              ]
            }
          },
          {
            "name": "mne",
            "in": "query",
            "description": "Whether the company is a constituent of a multinational group with consolidated revenue above AED 3.15bn, which is excluded from Small Business Relief (Ministerial Decision 73 of 2023 Article 3(1)). Default No.",
            "schema": {
              "type": "string",
              "enum": [
                "Yes",
                "No"
              ]
            }
          },
          {
            "name": "prevOver",
            "in": "query",
            "description": "Whether Revenue exceeded AED 3,000,000 in any earlier Tax Period, after which Small Business Relief is lost for good (Ministerial Decision 73 of 2023 Article 2(3)). Default No.",
            "schema": {
              "type": "string",
              "enum": [
                "Yes",
                "No"
              ]
            }
          },
          {
            "name": "elect",
            "in": "query",
            "description": "Whether Small Business Relief is elected for this Tax Period, which makes Taxable Income nil and stops Tax Losses and disallowed interest accruing (Article 21; Ministerial Decision 73 of 2023 Articles 2 and 4). The election is per period. Default No.",
            "schema": {
              "type": "string",
              "enum": [
                "Yes",
                "No"
              ]
            }
          },
          {
            "name": "bank",
            "in": "query",
            "description": "Whether the taxpayer is a bank, an insurance provider or a natural person, for whom the interest limitation does not apply (Article 30(6)). Default No.",
            "schema": {
              "type": "string",
              "enum": [
                "Yes",
                "No"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Taxable Income, Corporate Tax payable, the relief and QFZP tests, the carry-forwards, every computation step, basis and docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "The computation result. Every call returns all fourteen keys.",
                  "properties": {
                    "input": {
                      "type": "object",
                      "description": "The normalised inputs used, echoed back: the seven Yes/No flags as Yes or No and the twenty-two amounts as numbers.",
                      "properties": {},
                      "additionalProperties": true
                    },
                    "currency": {
                      "type": "string",
                      "description": "The currency of every amount, always AED.",
                      "enum": [
                        "AED"
                      ]
                    },
                    "eligible_small_business_relief": {
                      "type": "boolean",
                      "description": "Whether the Small Business Relief conditions are met: resident, Revenue at or below AED 3,000,000, no earlier period above it, not an MNE group member and not a QFZP."
                    },
                    "relief_applied": {
                      "type": "boolean",
                      "description": "Whether Small Business Relief was actually applied, that is eligible and elected, which sets Taxable Income to nil."
                    },
                    "qfzp": {
                      "type": "boolean",
                      "description": "Whether the person is treated as a Qualifying Free Zone Person: Free Zone Person, all conditions met and the de minimis test passed."
                    },
                    "de_minimis_passed": {
                      "type": "boolean",
                      "description": "Whether non-qualifying Revenue is within the de minimis threshold, the lower of 5 percent of Revenue and AED 5,000,000."
                    },
                    "taxable_income": {
                      "type": "number",
                      "description": "Taxable Income in AED after exempt income, non-deductible expenditure, the interest limitation and Tax Loss relief, floored at zero."
                    },
                    "corporate_tax_payable": {
                      "type": "number",
                      "description": "Corporate Tax payable in AED after the 0 percent band, the 9 percent rate and the Foreign Tax Credit, floored at zero."
                    },
                    "effective_rate_on_accounting_income": {
                      "type": "number",
                      "description": "Tax payable divided by Accounting Income, as a decimal fraction; zero when Accounting Income is not positive."
                    },
                    "losses_carried_forward": {
                      "type": "number",
                      "description": "Tax Losses carried to later periods in AED, after the relief used this period and any loss of the period itself."
                    },
                    "disallowed_interest_carried_forward": {
                      "type": "number",
                      "description": "Net Interest Expenditure carried forward in AED under Article 30(2), after this period's disallowance and any brought-forward amount used."
                    },
                    "steps": {
                      "type": "array",
                      "description": "The computation in the order Article 20(2) sets, one entry per line, each with the article behind it.",
                      "items": {
                        "type": "object",
                        "description": "One line of the computation.",
                        "properties": {
                          "line": {
                            "type": "string",
                            "description": "The label of the computation line, such as Accounting Income or Corporate Tax Payable."
                          },
                          "aed": {
                            "type": "number",
                            "description": "The amount for that line in AED, negative where the line is a deduction."
                          },
                          "basis": {
                            "type": "string",
                            "description": "The article or Decision the line rests on, such as Article 30(1) or Cabinet Decision 116 of 2022."
                          }
                        }
                      }
                    },
                    "basis": {
                      "type": "string",
                      "description": "The law and Decisions the computation rests on, with the note that it is not tax advice."
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the documentation section for this endpoint, https://bindler.co/api/#uae-corporate-tax"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request: the POST body was not valid JSON. Query parameter calls never reach this case.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned for an unusable request.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Always the text send JSON or query parameters.",
                      "enum": [
                        "send JSON or query parameters"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key: a value shaped like a Gumroad licence key was sent in x-api-key or ?key= and Gumroad did not verify it (refunded, charged back or cancelled purchases count as invalid).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned when the presented licence key does not verify.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Always the text invalid key.",
                      "enum": [
                        "invalid key"
                      ]
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the API documentation page, https://bindler.co/api/"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Free tier exhausted: more than 25 active minutes of calls from this IP in the current UTC day, and no verified key was sent. Send a key to remove the limit.",
            "headers": {
              "x-ratelimit-limit": {
                "description": "The free tier ceiling, the string 25.",
                "schema": {
                  "type": "string"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Remaining free calls, the string 0 on this response.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned when the free per-IP allowance is spent.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Explains the free tier ceiling and how to send a key."
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the API documentation page, https://bindler.co/api/"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "UAE Corporate Tax computation for one Tax Period, JSON body",
        "operationId": "uaeCorporateTaxPost",
        "description": "The same computation as GET, with the same fields sent in a JSON body. Omitted fields default to No, except resident which defaults to Yes, and to zero for amounts.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "rev": {
                    "type": "number",
                    "description": "Revenue for the Tax Period in AED, gross income and not profit (Article 21 and Ministerial Decision 73 of 2023 Article 2(4)); tested against the AED 3,000,000 Small Business Relief threshold."
                  },
                  "acc": {
                    "type": "number",
                    "description": "Accounting Income in AED: the net profit or loss before tax that starts the computation (Article 20(2))."
                  },
                  "ie": {
                    "type": "number",
                    "description": "Interest expenditure for the period in AED (Article 29). Feeds Net Interest Expenditure and the EBITDA of the interest limitation (Article 30(1))."
                  },
                  "ii": {
                    "type": "number",
                    "description": "Interest income for the period in AED, netted against interest expenditure in Net Interest Expenditure and in EBITDA (Article 30(1) and 30(2))."
                  },
                  "da": {
                    "type": "number",
                    "description": "Depreciation and amortisation charged in the period in AED, added back in the EBITDA used for the interest limitation (Article 30(1))."
                  },
                  "div": {
                    "type": "number",
                    "description": "Dividends and profit distributions from UAE resident juridical persons in AED, exempt without conditions (Article 22(1))."
                  },
                  "part": {
                    "type": "number",
                    "description": "Participation Exemption income in AED: dividends and gains from a Participating Interest, exempt where the conditions of Article 23 are met. Deducted from Accounting Income and from the EBITDA used for the interest limitation (Article 30(1))."
                  },
                  "oex": {
                    "type": "number",
                    "description": "Other exempt income in AED under Articles 22 and 24, such as income of a Foreign Permanent Establishment where that exemption applies (Article 24). Deducted from Accounting Income and from the EBITDA used for the interest limitation."
                  },
                  "ent": {
                    "type": "number",
                    "description": "Entertainment, amusement or recreation expenditure in AED; 50% is added back as non-deductible (Article 32(1))."
                  },
                  "fines": {
                    "type": "number",
                    "description": "Fines and penalties other than compensation for damages in AED, added back in full (Article 33(2))."
                  },
                  "don": {
                    "type": "number",
                    "description": "Donations, grants or gifts to entities that are not Qualifying Public Benefit Entities in AED, added back in full (Article 33(1))."
                  },
                  "dvo": {
                    "type": "number",
                    "description": "Dividends or other profit distributions to an owner that were charged to income in AED, added back in full as non-deductible (Article 33(4))."
                  },
                  "ctx": {
                    "type": "number",
                    "description": "Corporate Tax expense booked in the accounts in AED, added back in full because the tax itself is not a deductible expenditure (Article 33(6))."
                  },
                  "vat": {
                    "type": "number",
                    "description": "Recoverable input VAT charged to expense in AED, added back in full as non-deductible (Article 33(7))."
                  },
                  "ftx": {
                    "type": "number",
                    "description": "Foreign income tax charged to expense in AED, added back in full as non-deductible (Article 33(8)); relief for foreign tax comes through the Foreign Tax Credit line instead (Article 47)."
                  },
                  "nb": {
                    "type": "number",
                    "description": "Expenditure not incurred for the purposes of the Business in AED, added back as non-deductible (Article 28(2)(a))."
                  },
                  "exx": {
                    "type": "number",
                    "description": "Expenditure incurred in deriving Exempt Income in AED, added back as non-deductible together with the expenditure not incurred for the purposes of the Business (Article 28(2)(b))."
                  },
                  "loss": {
                    "type": "number",
                    "description": "Tax Losses carried forward from earlier Tax Periods in AED. Relief is capped at 75% of Taxable Income before relief (Article 37(2))."
                  },
                  "icf": {
                    "type": "number",
                    "description": "Disallowed Net Interest Expenditure brought forward from earlier periods in AED, deductible within the same 30% of EBITDA cap for ten periods (Article 30(4))."
                  },
                  "ftc": {
                    "type": "number",
                    "description": "Foreign Tax Credit available for the period in AED (Article 47), deducted from the Corporate Tax before credit and capped at it, so it cannot create a refund or a carry-forward (Article 47(2) and 47(3))."
                  },
                  "qi": {
                    "type": "number",
                    "description": "Qualifying Income of a Qualifying Free Zone Person in AED (Cabinet Decision No. 55 of 2023). Used only where the QFZP tests pass: 0% on this figure and 9% on Taxable Income above it (Article 3(2))."
                  },
                  "nqr": {
                    "type": "number",
                    "description": "Non-qualifying Revenue in AED, tested for the Free Zone de minimis rule: it must not exceed the lower of 5% of Revenue and AED 5,000,000, or Qualifying Free Zone Person status fails and the standard rates apply to everything (Ministerial Decision No. 139 of 2023, Article 4)."
                  },
                  "resident": {
                    "type": "string",
                    "enum": [
                      "Yes",
                      "No"
                    ],
                    "description": "Whether the taxpayer is a Resident Person (Article 11). Small Business Relief is available to Resident Persons only (Ministerial Decision 73 of 2023 Article 2). Default Yes."
                  },
                  "fz": {
                    "type": "string",
                    "enum": [
                      "Yes",
                      "No"
                    ],
                    "description": "Whether the taxpayer is a Free Zone Person (Article 18). Default No."
                  },
                  "qf": {
                    "type": "string",
                    "enum": [
                      "Yes",
                      "No"
                    ],
                    "description": "Whether every Qualifying Free Zone Person condition is met: substance, audited accounts, transfer pricing and no election out (Article 18(1)). With the de minimis test passed, the QFZP rates in Article 3(2) apply. Default No."
                  },
                  "mne": {
                    "type": "string",
                    "enum": [
                      "Yes",
                      "No"
                    ],
                    "description": "Whether the company is a constituent of a multinational group with consolidated revenue above AED 3.15bn, which is excluded from Small Business Relief (Ministerial Decision 73 of 2023 Article 3(1)). Default No."
                  },
                  "prevOver": {
                    "type": "string",
                    "enum": [
                      "Yes",
                      "No"
                    ],
                    "description": "Whether Revenue exceeded AED 3,000,000 in any earlier Tax Period, after which Small Business Relief is lost for good (Ministerial Decision 73 of 2023 Article 2(3)). Default No."
                  },
                  "elect": {
                    "type": "string",
                    "enum": [
                      "Yes",
                      "No"
                    ],
                    "description": "Whether Small Business Relief is elected for this Tax Period, which makes Taxable Income nil and stops Tax Losses and disallowed interest accruing (Article 21; Ministerial Decision 73 of 2023 Articles 2 and 4). The election is per period. Default No."
                  },
                  "bank": {
                    "type": "string",
                    "enum": [
                      "Yes",
                      "No"
                    ],
                    "description": "Whether the taxpayer is a bank, an insurance provider or a natural person, for whom the interest limitation does not apply (Article 30(6)). Default No."
                  }
                }
              },
              "example": {
                "rev": 2400000,
                "acc": 520000,
                "ie": 150000,
                "ii": 10000,
                "da": 60000,
                "div": 30000,
                "ent": 40000,
                "fines": 8000,
                "don": 5000,
                "nb": 6000,
                "loss": 120000,
                "elect": "No"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Taxable Income, Corporate Tax payable, the relief and QFZP tests, the carry-forwards, every computation step, basis and docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "The computation result. Every call returns all fourteen keys.",
                  "properties": {
                    "input": {
                      "type": "object",
                      "description": "The normalised inputs used, echoed back: the seven Yes/No flags as Yes or No and the twenty-two amounts as numbers.",
                      "properties": {},
                      "additionalProperties": true
                    },
                    "currency": {
                      "type": "string",
                      "description": "The currency of every amount, always AED.",
                      "enum": [
                        "AED"
                      ]
                    },
                    "eligible_small_business_relief": {
                      "type": "boolean",
                      "description": "Whether the Small Business Relief conditions are met: resident, Revenue at or below AED 3,000,000, no earlier period above it, not an MNE group member and not a QFZP."
                    },
                    "relief_applied": {
                      "type": "boolean",
                      "description": "Whether Small Business Relief was actually applied, that is eligible and elected, which sets Taxable Income to nil."
                    },
                    "qfzp": {
                      "type": "boolean",
                      "description": "Whether the person is treated as a Qualifying Free Zone Person: Free Zone Person, all conditions met and the de minimis test passed."
                    },
                    "de_minimis_passed": {
                      "type": "boolean",
                      "description": "Whether non-qualifying Revenue is within the de minimis threshold, the lower of 5 percent of Revenue and AED 5,000,000."
                    },
                    "taxable_income": {
                      "type": "number",
                      "description": "Taxable Income in AED after exempt income, non-deductible expenditure, the interest limitation and Tax Loss relief, floored at zero."
                    },
                    "corporate_tax_payable": {
                      "type": "number",
                      "description": "Corporate Tax payable in AED after the 0 percent band, the 9 percent rate and the Foreign Tax Credit, floored at zero."
                    },
                    "effective_rate_on_accounting_income": {
                      "type": "number",
                      "description": "Tax payable divided by Accounting Income, as a decimal fraction; zero when Accounting Income is not positive."
                    },
                    "losses_carried_forward": {
                      "type": "number",
                      "description": "Tax Losses carried to later periods in AED, after the relief used this period and any loss of the period itself."
                    },
                    "disallowed_interest_carried_forward": {
                      "type": "number",
                      "description": "Net Interest Expenditure carried forward in AED under Article 30(2), after this period's disallowance and any brought-forward amount used."
                    },
                    "steps": {
                      "type": "array",
                      "description": "The computation in the order Article 20(2) sets, one entry per line, each with the article behind it.",
                      "items": {
                        "type": "object",
                        "description": "One line of the computation.",
                        "properties": {
                          "line": {
                            "type": "string",
                            "description": "The label of the computation line, such as Accounting Income or Corporate Tax Payable."
                          },
                          "aed": {
                            "type": "number",
                            "description": "The amount for that line in AED, negative where the line is a deduction."
                          },
                          "basis": {
                            "type": "string",
                            "description": "The article or Decision the line rests on, such as Article 30(1) or Cabinet Decision 116 of 2022."
                          }
                        }
                      }
                    },
                    "basis": {
                      "type": "string",
                      "description": "The law and Decisions the computation rests on, with the note that it is not tax advice."
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the documentation section for this endpoint, https://bindler.co/api/#uae-corporate-tax"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request: the POST body was not valid JSON. Query parameter calls never reach this case.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned for an unusable request.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Always the text send JSON or query parameters.",
                      "enum": [
                        "send JSON or query parameters"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key: a value shaped like a Gumroad licence key was sent in x-api-key or ?key= and Gumroad did not verify it (refunded, charged back or cancelled purchases count as invalid).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned when the presented licence key does not verify.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Always the text invalid key.",
                      "enum": [
                        "invalid key"
                      ]
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the API documentation page, https://bindler.co/api/"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Free tier exhausted: more than 25 active minutes of calls from this IP in the current UTC day, and no verified key was sent. Send a key to remove the limit.",
            "headers": {
              "x-ratelimit-limit": {
                "description": "The free tier ceiling, the string 25.",
                "schema": {
                  "type": "string"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Remaining free calls, the string 0 on this response.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error body returned when the free per-IP allowance is spent.",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Explains the free tier ceiling and how to send a key."
                    },
                    "docs": {
                      "type": "string",
                      "description": "Link to the API documentation page, https://bindler.co/api/"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "options": {
        "summary": "CORS preflight for the UAE Corporate Tax endpoint",
        "operationId": "uaeCorporateTaxOptions",
        "description": "Answers the browser preflight with the allowed origin, methods and headers, and no body.",
        "security": [],
        "responses": {
          "204": {
            "description": "CORS preflight answered with no body. The endpoint replies to OPTIONS before any key check or rate limiting.",
            "headers": {
              "access-control-allow-origin": {
                "description": "Always the wildcard star, any origin may call.",
                "schema": {
                  "type": "string"
                }
              },
              "access-control-allow-methods": {
                "description": "The methods allowed, the string GET, POST, OPTIONS.",
                "schema": {
                  "type": "string"
                }
              },
              "access-control-allow-headers": {
                "description": "The headers allowed, content-type and x-api-key.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  },
  "security": [
    {
      "ApiKey": []
    },
    {
      "ApiKeyQuery": []
    },
    {}
  ]
}
