> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scaledown.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrate Decisions

> Copy-paste AI prompts to generate integration code for the /v1/scaledown endpoint.

Copy one of these prompts into Claude, ChatGPT, or any AI assistant to generate integration code for the `/v1/scaledown` endpoint. Start with the **quick integration** prompt to get something working fast, or use the **production-ready** prompt if you're building for a live environment.

## Prompts

### Quick integration

Paste this prompt to generate a minimal Python function - useful for prototyping or one-off scripts, and for porting an existing Jev (TypeSafe) integration.

```text Quick integration prompt theme={null}
Write a Python function `answer_decisions(state: dict, questions: dict, api_key: str) -> dict`
that calls the ScaleDown decisions API and returns the full response as a dict.

API details:
- Endpoint: POST https://api.scaledown.xyz/v1/scaledown
- Auth: HTTP header `x-api-key: <your key>`
- Request body (JSON):
    {
      "model": "classify-1",                         // optional; "classify-1" is the only
                                                       // supported value and also the default
      "state": {
        "text": "<text to evaluate>",                // optional if document is provided
        "document": "<base64-encoded file>",          // optional; image or PDF
        "document_mime_type": "image/jpeg"             // required when document is set
      },
      "questions": {
        "<question_name>": {
          "type": "choice",                            // "choice" | "noul" | "score"
          "instructions": "<optional guidance>",
          "criteria": { "<option_key>": "<option description>", ... }  // required for "choice" only
        }
      }
    }
  This mirrors TypeSafe's Jev Decisions API (POST /api/alpha/decisions on OpenRouter) request
  shape. Sending a "model" value other than "classify-1" returns 422. "score" questions are
  accepted but never actually evaluated: if the request has at least one choice/noul question
  too, the score question(s) come back as "unsupported" (see below) and everything else is
  still answered; if EVERY question is "score", the whole request returns 422 instead.
- Success response (JSON):
    {
      "model": "classify-1",
      "answers": {
        "<question_name>": {
          // "choice" type:
          "type": "choice", "choice": "billing",
          "probabilities": { "billing": 0.93, "technical": 0.07 }, "confidence": 0.93
          // OR "noul" type:
          // "type": "noul", "noul": 0.79
          // OR "score" type (always this, never a real score):
          // "type": "unsupported", "reason": "'score' questions are not supported by this API"
        }
      },
      "usage": { "input_tokens": 62, "output_tokens": 1, "cost": 0.0000026 }
    }
- Error responses: 422 (malformed body, empty questions map, empty criteria on a choice
  question, neither state.text nor state.document provided, every question is type "score",
  or "model" is anything other than "classify-1"), 402 (insufficient credits),
  502 (model service error), 504 (timeout)

Requirements:
- The state parameter is a dict passed through as the request's "state" field.
- The questions parameter is a dict passed through as the request's "questions" field.
- Accept the API key as the third parameter.
- Raise a ValueError with a descriptive message on any non-2xx HTTP response,
  including the status code and response body in the message.
- Return the full parsed response dict on success.
```

### Production-ready

Paste this prompt to generate a fully typed Python service class with error handling, retries, and environment-variable-based configuration.

```text Production-ready prompt theme={null}
Write a production-quality Python module for integrating the ScaleDown decisions API.

API details:
- Endpoint: POST https://api.scaledown.xyz/v1/scaledown
- Auth: HTTP header `x-api-key: <your key>`, read from the DECISIONS_API_KEY environment
  variable if not passed explicitly.
- Request body: { "model"?: str, "state": { "text"?: str, "document"?: str,
  "document_mime_type"?: str }, "questions": { name: { "type": "choice"|"noul"|"score",
  "instructions"?: str, "criteria"?: { key: str } } } }. "criteria" is required for "choice"
  questions and ignored otherwise. Either state.text or state.document is required. "model"
  defaults to "classify-1" and is the ONLY accepted value - any other value is a 422.
- Response: { "model": str, "answers": { name: ChoiceAnswer | NoulAnswer | UnsupportedAnswer },
  "usage": { "input_tokens": int, "output_tokens": int, "cost": float } }
  - ChoiceAnswer: { "type": "choice", "choice": str, "probabilities": dict[str, float],
    "confidence": float }
  - NoulAnswer: { "type": "noul", "noul": float }  # probability 0-1
  - UnsupportedAnswer: { "type": "unsupported", "reason": str }  # returned for a "score"
    question ONLY when the request also has a choice/noul question - there is no
    ordered-scale scoring in this API today. If EVERY question in the request is "score",
    the whole request fails with 422 instead of returning any UnsupportedAnswer.
- Errors: 422 malformed/validation (including an unsupported "model" value, or a request made
  entirely of "score" questions), 402 insufficient credits, 502 upstream model error,
  504 timeout. Non-2xx responses include a JSON body with a "detail" field.

Requirements:
- Use dataclasses (or Pydantic if available) to model the request questions (Choice, Noul,
  Score variants) and the typed answers (ChoiceAnswer, NoulAnswer, UnsupportedAnswer) so
  callers get type-safe access rather than raw dicts, with a discriminator on "type".
- Implement retry with exponential backoff (starting at 1s, capped at 30s, with jitter) on
  429 and 5xx responses. Do not retry on 4xx other than 429.
- Raise a typed exception hierarchy: DecisionsAuthError (401/403), DecisionsQuotaError (402),
  DecisionsValidationError (422), DecisionsServerError (502/504/other 5xx).
- Log each request's latency and usage.cost at debug level.
- Include a synchronous class `DecisionsClient` with a method
  `ask(state: dict, questions: dict, model: str | None = None) -> DecisionsResponse`.
- Include type hints throughout and a minimal usage example in a `if __name__ == "__main__":`
  block showing a mixed choice + noul request.
```

## Porting from Jev

If you have existing code calling `POST https://openrouter.ai/api/alpha/decisions`, porting to `/v1/scaledown` is mostly a base-URL and auth-header swap:

|                             | Jev                                         | ScaleDown `/v1/scaledown`                                                                                                                                   |
| --------------------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| URL                         | `https://openrouter.ai/api/alpha/decisions` | `https://api.scaledown.xyz/v1/scaledown`                                                                                                                    |
| Auth header                 | `Authorization: Bearer <key>`               | `x-api-key: <key>`                                                                                                                                          |
| `choice` / `noul` questions | ✅                                           | ✅ unchanged                                                                                                                                                 |
| `score` questions           | ✅ real answer                               | ❌ `"unsupported"` in a mixed request; `422` if the whole request is `score` - see [Unsupported: score](/api-reference/decisions-overview#unsupported-score) |
| `model` selection           | Multiple models                             | Only `"classify-1"` - any other value is `422`                                                                                                              |

Everything else - the `state`/`questions` request shape and the `answers`/`usage` response shape - is unchanged. See [Overview](/api-reference/decisions-overview) for the full compatibility notes.
