dilem.

    API, MCP and agents

    Developer documentation

    An agent can submit a choice, receive a clarifying question, then get a recommendation with its reasons. No account or provider key is required.

    REST v1.1.0 MCP · Streamable HTTP Markdown ↗

    MCP

    For assistants and MCP clients. Configure the server, then discover its tools.

    REST API

    For your application or script. HTTP, Bearer authentication and JSON responses.

    WebMCP

    For an agent in the open page. Uses browser identity and history.

    Connect with MCP

    MCP address
    https://dilem.si/api/v1/mcp

    Remote HTTP transport, without OAuth. Pass the application token to tools, not in the server configuration. Allow 110 seconds for a decision call.

    Choose your client. Merge the example into your existing configuration rather than replacing it. Reload MCP tools, then check that start_session, get_usage and decide are available.

    Claude Code
    Terminal · Bash
    claude mcp add --transport http dilem https://dilem.si/api/v1/mcp

    Client documentation ↗

    Codex
    Configuration file
    ~/.codex/config.toml
    Configuration · TOML
    [mcp_servers.dilem]
    url = "https://dilem.si/api/v1/mcp"
    tool_timeout_sec = 110

    Client documentation ↗

    Cursor
    Configuration file
    .cursor/mcp.json
    Configuration · JSON
    {
      "mcpServers": {
        "dilem": {
          "url": "https://dilem.si/api/v1/mcp"
        }
      }
    }

    Client documentation ↗

    OpenCode
    Configuration file
    opencode.json
    Configuration · JSON
    {
      "mcp": {
        "dilem": {
          "type": "remote",
          "url": "https://dilem.si/api/v1/mcp",
          "enabled": true,
          "oauth": false
        }
      }
    }

    Client documentation ↗

    Hermes Agent
    Terminal · Bash
    hermes mcp add dilem --url https://dilem.si/api/v1/mcp

    Client documentation ↗

    Mistral Vibe
    Configuration file
    ~/.vibe/config.toml
    Configuration · TOML
    [[mcp_servers]]
    name = "dilem"
    transport = "streamable-http"
    url = "https://dilem.si/api/v1/mcp"
    tool_timeout_sec = 110
    
    [mcp_servers.auth]
    type = "static"
    headers = {}

    Client documentation ↗

    OpenClaw
    Configuration file
    ~/.openclaw/openclaw.json
    Configuration · JSON
    {
      "mcp": {
        "servers": {
          "dilem": {
            "url": "https://dilem.si/api/v1/mcp",
            "transport": "streamable-http",
            "enabled": true,
            "connectionTimeoutMs": 10000,
            "requestTimeoutMs": 110000
          }
        }
      }
    }

    Client documentation ↗

    Pi
    Configuration file
    ~/.pi/agent/mcp.json
    Configuration · JSON
    {
      "mcpServers": {
        "dilem": {
          "url": "https://dilem.si/api/v1/mcp",
          "timeout": 110
        }
      }
    }

    Client documentation ↗

    MCP reference

    Create or renew the client’s private identity.

    • session string | null optional · Default null

    Response: Session

    POST /api/v1/session

    Input

    Headers
    • Authorization string

      Session token sent as Bearer <session>.

    No request body required.

    Response

    200 application/json
    Illustrative example · JSON
    {
      "session": "OPAQUE_SESSION_KEEP_PRIVATE",
      "expires_in": 7776000
    }
    • session string · required

      Private client token to retain for subsequent calls.

    • expires_in integer · required

      Session validity period, in seconds.

      Value: 7776000

    Errors and recovery

    403 · 408 · 409 · 413 · 422 · 429 · 503 application/json

    Illustrative example · JSON
    {
      "type": "error",
      "code": "case_completed"
    }
    • type string · required

      Kind of response returned.

      Value: "error"

    • code string · required

      Code to inspect when handling a refusal or failure.

    • message string

      Readable explanation of the refusal or failure.

    • retryable boolean

      Whether another attempt may be considered.

    • resets_at string

      Date and time of the next credit reset.

      ISO 8601 date and time

    Read credits, reset time and optional case state.

    • session string required
    • case_id string | null optional · Default null

    Response: Usage

    GET /api/v1/usage

    Input

    Headers
    • Authorization string · required

      Session token sent as Bearer <session>.

    • X-Dilem-Case-ID string

      Keep this identifier for every turn of the same dilemma.

      Technical format

      ^[a-zA-Z0-9_-]{1,80}$

    No request body required.

    Response

    200 application/json
    Illustrative example · JSON
    {
      "day": "2026-01-01",
      "resets_at": "2026-01-02T00:00:00Z",
      "collective": {
        "completed": 42
      },
      "dilemmas": {
        "used": 1,
        "limit": 20,
        "remaining": 19
      },
      "case": {
        "id": "my-unique-dilemma-id",
        "admitted": true,
        "completed": false
      },
      "voice": {
        "seconds_used": 0,
        "seconds_reserved": 0,
        "seconds_remaining": 1200,
        "seconds_limit": 1200,
        "max_seconds": 60
      },
      "budget": {
        "daily_usd": 5,
        "available": true
      }
    }
    • day string · required

      UTC day of the counters.

      ISO 8601 date

    • resets_at string · required

      Date and time of the next credit reset.

      ISO 8601 date and time

    • collective object · required

      Shared count of completed dilemmas.

      Fields
      • completed integer · required

        Number of completed dilemmas in the shared counter.

    • dilemmas object · required

      Used, remaining and allowed dilemma credits.

      Fields
      • used integer · required

        Credits already used.

        Minimum: 0

      • limit integer · required

        Credit limit from the active policy.

        Minimum: 0

      • remaining integer · required

        Credits still available.

        Minimum: 0

    • case object · required

      State of the dilemma identified by the supplied Case-ID.

      Fields
      • id string | null · required

        Requested Case-ID, or null when none was supplied.

      • admitted boolean · required

        Whether this dilemma has already been admitted under the quota.

      • completed boolean · required

        Whether a first recommendation completed this dilemma.

    • voice object · required

      Dictation durations and limits, in seconds.

      Fields
      • seconds_used number

        Dictation seconds already used.

      • seconds_reserved number

        Seconds temporarily reserved by an active capture.

      • seconds_remaining number

        Dictation seconds still available.

      • seconds_limit number

        Total dictation limit, in seconds.

      • max_seconds number

        Maximum capture duration, in seconds.

    • budget object · required

      Shared financial budget and service availability.

      Fields
      • daily_usd number · required

        Daily service budget limit, in US dollars.

      • available boolean · required

        Whether the budget still allows calculations.

    Errors and recovery

    403 · 408 · 409 · 413 · 422 · 429 · 503 application/json

    Illustrative example · JSON
    {
      "type": "error",
      "code": "case_completed"
    }
    • type string · required

      Kind of response returned.

      Value: "error"

    • code string · required

      Code to inspect when handling a refusal or failure.

    • message string

      Readable explanation of the refusal or failure.

    • retryable boolean

      Whether another attempt may be considered.

    • resets_at string

      Date and time of the next credit reset.

      ISO 8601 date and time

    decide

    AI calculation

    Submit a decision turn: question, recommendation or error.

    • session string required
    • case_id string required
    • text string required
    • language "fr" | "en" | "it" | "de" | "es" | "pt" optional · Default "fr"
    • refinements string[] | null optional · Default null
    • force_decision boolean optional · Default false
    • clarification_count integer optional · Default 0
    • clarification_version 2 optional · Default 2

    Response: DecisionResponse

    POST /api/v1/decide

    Input

    Headers
    • Authorization string · required

      Session token sent as Bearer <session>.

    • X-Dilem-Case-ID string · required

      Keep this identifier for every turn of the same dilemma.

      Technical format

      ^[a-zA-Z0-9_-]{1,80}$

    Body application/json
    REST · Request · Illustrative example · JSON
    {
      "text": "Train or bus for my commute?",
      "language": "en",
      "refinements": [],
      "clarification_version": 2
    }
    • text string · required

      Initial choice, retained on every turn.

      1–6 000 characters

    • language string · required

      Interface language. Replies follow the user’s own words.

      Allowed values: "fr", "en", "it", "de", "es", "pt"

    • refinements string[]

      Actual questions and answers in chronological order.

      Up to 40 items · Up to 6 000 characters per item · Default: []

    • force_decision boolean

      Only when the user requests a recommendation without further questions.

      Default: false

    • clarification_count integer

      Number of clarification answers.

      0–20 · Default: 0

    • clarification_version integer

      Contract version, always 2.

      Default: 2 · Value: 2

    MCP · decide · Request · JSON
    {
      "session": "<session from start_session>",
      "case_id": "my-unique-dilemma-id",
      "text": "Train or car for a weekend trip?",
      "language": "en"
    }

    Response

    200 application/json
    Clarifying question Clarification

    A question to relay, or a notice according to purpose. insufficient_evidence means there is no defensible basis for ranking; do not retry without new information from the user.

    Illustrative example · JSON
    {
      "type": "clarification",
      "question": "How far is your commute?",
      "choices": [],
      "format": "number",
      "unit": "km",
      "summary": "Train or bus"
    }
    • type string · required

      Kind of response returned.

      Value: "clarification"

    • question string · required

      Question to relay to the user before continuing.

    • choices string[] · required

      Suggested answers, when supplied with the question.

      Up to 6 items

    • format string · required

      Answer format expected by the question.

      Allowed values: "single", "multiple", "text", "number"

    • unit string | null

      Unit of a numeric answer, or null.

    • summary string · required

      Summary of the dilemma.

    • purpose string

      Purpose of the question or scope notice.

      Allowed values: "decision_scope", "scope_notice", "insufficient_evidence"

    • metrics object

      Technical processing metrics.

    Recommendation Result

    Recommendation, options, reasons and sources. Weights express relative preferences, not success probabilities. result_id may be absent.

    Illustrative example · JSON
    {
      "type": "result",
      "summary": "Train or bus for my commute?",
      "options": [
        {
          "id": "train",
          "label": "Take the train",
          "description": "Use the direct rail connection.",
          "probability": 0.7
        },
        {
          "id": "bus",
          "label": "Take the bus",
          "description": "Use the bus stop near home.",
          "probability": 0.3
        }
      ],
      "selected": "train",
      "sources": [],
      "result_id": "0123456789abcdef0123456789abcdef"
    }
    • type string · required

      Kind of response returned.

      Value: "result"

    • summary string · required

      Summary of the dilemma.

    • context string

      Context used for the recommendation.

    • assumptions string[]

      Assumptions used to compare options.

    • criteria string[]

      Criteria used to compare options.

    • options object[] · required

      Compared options and associated information.

      2–8 items

    • selected string · required

      Identifier of the recommended option.

    • sources object[] · required

      Sources returned with the recommendation.

    • caution string | null

      Specific caution, or null.

    • timings object

      Durations of processing stages.

    • models object

      Model information for this turn.

    • metrics object

      Technical processing metrics.

    • result_id string

      Identifier of a result owned by this client.

    Error Error

    Pipeline refusal or failure. Check type even after HTTP 200; MCP also reports isError.

    Illustrative example · JSON
    {
      "type": "error",
      "code": "case_completed"
    }
    • type string · required

      Kind of response returned.

      Value: "error"

    • code string · required

      Code to inspect when handling a refusal or failure.

    • message string

      Readable explanation of the refusal or failure.

    • retryable boolean

      Whether another attempt may be considered.

    • resets_at string

      Date and time of the next credit reset.

      ISO 8601 date and time

    Errors and recovery

    403 · 408 · 409 · 413 · 422 · 429 · 503 application/json

    Illustrative example · JSON
    {
      "type": "error",
      "code": "case_completed"
    }
    • type string · required

      Kind of response returned.

      Value: "error"

    • code string · required

      Code to inspect when handling a refusal or failure.

    • message string

      Readable explanation of the refusal or failure.

    • retryable boolean

      Whether another attempt may be considered.

    • resets_at string

      Date and time of the next credit reset.

      ISO 8601 date and time

    Render the received result as a card, without AI or image storage.

    • session string required
    • result CardResult required
    • language "fr" | "en" | "it" | "de" | "es" | "pt" optional · Default "fr"
    • theme "light" | "dark" optional · Default "light"

    Response: image/png

    POST /api/v1/result-card

    Input

    Headers
    • Authorization string · required

      Session token sent as Bearer <session>.

    Body application/json
    REST · Request · Illustrative example · JSON
    {
      "result": {
        "summary": "Train or bus for my commute?",
        "selected": "train",
        "options": [
          {
            "id": "train",
            "label": "Take the train",
            "description": "Use the direct rail connection.",
            "probability": 0.7
          },
          {
            "id": "bus",
            "label": "Take the bus",
            "description": "Use the bus stop near home.",
            "probability": 0.3
          }
        ]
      },
      "language": "en",
      "theme": "light"
    }
    • result CardResult · required

      Previously received result to supply for PNG rendering.

      Fields
      • summary string · required

        Summary of the dilemma.

        1–6 000 characters

      • selected string · required

        Identifier of the recommended option.

        Up to 32 characters

      • options CardOption[] · required

        Compared options and associated information.

        2–8 items

        Fields
        • id string · required

          Unique identifier of this option within the result.

          Technical format

          ^[a-z][a-z0-9_]{0,31}$

        • label string · required

          Option label on the card.

          1–120 characters

        • description string

          Short description shown with the option.

          Up to 240 characters · Default: ""

        • probability number · required

          Preference weight, not a probability of success.

          0–1

    • language string

      Presentation language.

      Allowed values: "fr", "en", "it", "de", "es", "pt" · Default: "fr"

    • theme string

      Visual theme of the PNG card.

      Allowed values: "light", "dark" · Default: "light"

    Response

    200 image/png

    Private PNG attachment. Its filename is returned in Content-Disposition.

    Errors and recovery

    403 · 408 · 409 · 413 · 422 · 429 · 503 · 415 application/json

    Illustrative example · JSON
    {
      "type": "error",
      "code": "case_completed"
    }
    • type string · required

      Kind of response returned.

      Value: "error"

    • code string · required

      Code to inspect when handling a refusal or failure.

    • message string

      Readable explanation of the refusal or failure.

    • retryable boolean

      Whether another attempt may be considered.

    • resets_at string

      Date and time of the next credit reset.

      ISO 8601 date and time

    Read the owning client’s result vote.

    • session string required
    • result_id string required

    Response: Feedback

    GET /api/v1/feedback/{result_id}

    Input

    Headers
    • Authorization string · required

      Session token sent as Bearer <session>.

    Path parameters
    • result_id string · required

      Identifier of a result owned by this client.

      Technical format

      ^[0-9a-f]{32}$

    No request body required.

    Response

    200 application/json
    Illustrative example · JSON
    {
      "result_id": "0123456789abcdef0123456789abcdef",
      "helpful": false,
      "reason": "missing_constraint"
    }
    • result_id string · required

      Identifier of a result owned by this client.

      Technical format

      ^[0-9a-f]{32}$

    • helpful boolean | null · required

      Recorded vote, or null when no vote was given.

    • reason null | string · required

      Reason for a negative vote, or null.

      Allowed values: null, "misunderstood", "missing_constraint", "too_many_questions", "too_vague"

    Errors and recovery

    403 · 408 · 409 · 413 · 422 · 429 · 503 · 404 application/json

    Illustrative example · JSON
    {
      "type": "error",
      "code": "case_completed"
    }
    • type string · required

      Kind of response returned.

      Value: "error"

    • code string · required

      Code to inspect when handling a refusal or failure.

    • message string

      Readable explanation of the refusal or failure.

    • retryable boolean

      Whether another attempt may be considered.

    • resets_at string

      Date and time of the next credit reset.

      ISO 8601 date and time

    Record the user’s explicit vote; never infer satisfaction.

    • session string required
    • result_id string required
    • helpful boolean required
    • reason "misunderstood" | "missing_constraint" | "too_many_questions" | "too_vague" | null optional · Default null

    Response: Feedback

    POST /api/v1/feedback

    Input

    Headers
    • Authorization string · required

      Session token sent as Bearer <session>.

    Body application/json
    REST · Request · Illustrative example · JSON
    {
      "result_id": "0123456789abcdef0123456789abcdef",
      "helpful": false,
      "reason": "missing_constraint"
    }
    • result_id string · required

      Identifier of a result owned by this client.

      Technical format

      ^[0-9a-f]{32}$

    • helpful boolean · required

      User’s explicit vote on the response.

    • reason null | string

      Reason for a negative vote, or null.

      Allowed values: null, "misunderstood", "missing_constraint", "too_many_questions", "too_vague"

    Response

    200 application/json
    Illustrative example · JSON
    {
      "result_id": "0123456789abcdef0123456789abcdef",
      "helpful": false,
      "reason": "missing_constraint"
    }
    • result_id string · required

      Identifier of a result owned by this client.

      Technical format

      ^[0-9a-f]{32}$

    • helpful boolean | null · required

      Recorded vote, or null when no vote was given.

    • reason null | string · required

      Reason for a negative vote, or null.

      Allowed values: null, "misunderstood", "missing_constraint", "too_many_questions", "too_vague"

    Errors and recovery

    403 · 408 · 409 · 413 · 422 · 429 · 503 · 415 · 404 application/json

    Illustrative example · JSON
    {
      "type": "error",
      "code": "case_completed"
    }
    • type string · required

      Kind of response returned.

      Value: "error"

    • code string · required

      Code to inspect when handling a refusal or failure.

    • message string

      Readable explanation of the refusal or failure.

    • retryable boolean

      Whether another attempt may be considered.

    • resets_at string

      Date and time of the next credit reset.

      ISO 8601 date and time

    Send an explicitly authorized message or report.

    • session string required
    • request_id string required
    • message string required
    • language "fr" | "en" | "it" | "de" | "es" | "pt" optional · Default "fr"
    • kind "general" | "response" optional · Default "general"
    • email string optional · Default ""
    • response object | null optional · Default null

    Response: FeedbackAck

    POST /api/v1/user-feedback

    Input

    Headers
    • Authorization string · required

      Session token sent as Bearer <session>.

    Body application/json
    REST · Request · Illustrative example · JSON
    {
      "request_id": "0123456789abcdef0123456789abcdef",
      "kind": "general",
      "message": "Please explain how the recommendation uses my constraints.",
      "email": "",
      "language": "en",
      "source": "agent",
      "version": "unknown",
      "screen": "other",
      "response": null
    }
    • request_id string · required

      Identifier to retain for deduplicating the same submission.

      Technical format

      ^[0-9a-f]{32}$

    • kind string · required

      General message or report of a response.

      Allowed values: "general", "response"

    • message string · required

      Comment expressly provided by the user.

      5–4 000 characters

    • email string · required

      Contact address, or an empty string.

      Up to 254 characters

    • language string · required

      Presentation language.

      Allowed values: "fr", "en", "it", "de", "es", "pt"

    • source string · required

      Entry point from which the message originated.

      Allowed values: "agent", "menu", "help", "response"

    • version string · required

      Application SHA, or unknown.

      Technical format

      ^[0-9a-f]{40}$|^unknown$

    • screen string · required

      Screen from which the message is sent.

      Allowed values: "home", "clarification", "result", "other"

    • response null | ReportedResponse · required

      Exact response attached to the report, otherwise null.

      Fields
      null

      null

      Attached response ReportedResponse
      • kind string · required

        Kind of response attached to the report.

        Allowed values: "clarification", "recommendation"

      • text string · required

        Exact text of the attached response.

        1–12 000 characters

      • reference string · required

        Reference of the response concerned.

        Technical format

        ^[A-Za-z0-9._:-]{1,80}$

    Response

    200 application/json
    Illustrative example · JSON
    {
      "ok": true
    }
    • ok boolean · required

      Confirms the message was recorded.

      Value: true

    Errors and recovery

    403 · 408 · 409 · 413 · 422 · 429 · 503 · 415 application/json

    Illustrative example · JSON
    {
      "type": "error",
      "code": "case_completed"
    }
    • type string · required

      Kind of response returned.

      Value: "error"

    • code string · required

      Code to inspect when handling a refusal or failure.

    • message string

      Readable explanation of the refusal or failure.

    • retryable boolean

      Whether another attempt may be considered.

    • resets_at string

      Date and time of the next credit reset.

      ISO 8601 date and time

    Quickstart

    Requires curl and Python 3. Create an identity once, store its token privately and restore it on later visits.

    Create a session and save the session value. Send it as Authorization: Bearer *** on subsequent calls. It lasts 90 days; renew it with the same call and token.

    POST /api/v1/session · Bash
    DILEM_SESSION=$(curl --fail-with-body --silent --show-error --max-time 15 \
      https://dilem.si/api/v1/session \
      -H 'Content-Type: application/json' -d '{}' | \
      python3 -c 'import json, sys; print(json.load(sys.stdin)["session"])')
    GET /api/v1/usage · Bash
    curl --fail-with-body --max-time 15 https://dilem.si/api/v1/usage \
      -H "Authorization: Bearer ${DILEM_SESSION:?}" \
      -H 'X-Dilem-Case-ID: my-unique-dilemma-id'

    Choose a Case-ID for your dilemma and keep it throughout the conversation. You receive a question or a recommendation. To answer, append the question and your answer to refinements, then increment clarification_count by 1.

    POST /api/v1/decide · Bash
    curl --fail-with-body --max-time 110 --output result.json https://dilem.si/api/v1/decide \
      -H "Authorization: Bearer ${DILEM_SESSION:?}" \
      -H 'X-Dilem-Case-ID: my-unique-dilemma-id' \
      -H 'Content-Type: application/json' \
      -d '{"text":"Train or car for a weekend trip?","language":"en","refinements":[],"clarification_count":0,"clarification_version":2}'

    Session and authentication

    Without a token, start_session creates an identity. With session, it renews the same identity for 90 days. Invalid or expired tokens are refused, never silently replaced. REST and MCP share this token; neither reads browser cookies.

    Use one unique Case-ID per dilemma until its result: 1–80 characters from a-z, A-Z, 0-9, _ and -. It identifies the case, but does not make a calculation idempotent.

    Dilemma lifecycle

    1. Submit the initial choice with a new Case-ID.
    2. On clarification, inspect purpose: insufficient_evidence is a notice to show, not a question or invitation to invent a ranking. Otherwise ask the question and wait for the actual answer; append question + answer to refinements and increment clarification_count.
    3. On result, retain the JSON: this case is complete. Use a new Case-ID for another calculation.
    4. On error, inspect code and retryable. Never automatically replay a calculation after an ambiguous outcome.

    The agent passes questions to you and waits for your answers, without inventing missing information. You can ask it for a recommendation without further questions.

    Decision parameters

    • text required

      Initial choice, retained on every turn.

      string · 1–6000
    • language required

      Interface language. Replies follow the user’s own words.

      fr | en | it | de | es | pt
    • refinements optional

      Actual questions and answers in chronological order.

      array · ≤40 × 6000
    • clarification_count optional

      Number of clarification answers.

      integer · 0–20
    • clarification_version optional

      Contract version, always 2.

      2
    • force_decision optional

      Only when the user requests a recommendation without further questions.

      boolean

    Text + refinements: 24,000 characters total. HTTP body: 300,000 bytes received within 10 seconds; an oversized provider envelope can also be refused before consumption.

    Responses

    Clarifying question type: clarification

    A question to relay, or a notice according to purpose. insufficient_evidence means there is no defensible basis for ranking; do not retry without new information from the user.

    type, question, choices, format, unit, summary, purpose, metrics

    Recommendation type: result

    Recommendation, options, reasons and sources. Weights express relative preferences, not success probabilities. result_id may be absent.

    type, summary, context, assumptions, criteria, options, selected, sources, caution, timings, models, metrics, result_id

    Error type: error

    Pipeline refusal or failure. Check type even after HTTP 200; MCP also reports isError.

    type, code, message, retryable, resets_at

    Illustrative example · clarification · JSON
    {
      "type": "clarification",
      "question": "How far is your commute?",
      "choices": [],
      "format": "number",
      "unit": "km",
      "summary": "Train or bus"
    }

    Results and feedback

    Export a result as PNG

    Pass the received result as result, with language and theme (light or dark). Private PNG, filename in Content-Disposition, Cache-Control: no-store. No dilemma credit and no publication. MCP returns a native image and file metadata.

    Request · Illustrative example · Bash
    python3 -c 'import json, sys; print(json.dumps({"result": json.load(sys.stdin), "language": "fr", "theme": "light"}))' < result.json > card-input.json
    POST /api/v1/result-card · Bash
    curl --fail-with-body --max-time 15 https://dilem.si/api/v1/result-card \
      -H "Authorization: Bearer ${DILEM_SESSION:?}" \
      -H "Content-Type: application/json" \
      --data-binary @card-input.json --output dilem.png

    Read or record a vote

    result_id belongs to this identity. helpful is a boolean; reason is optional for a negative vote only: misunderstood, missing_constraint, too_many_questions or too_vague. Missing, expired and foreign results return the same 404.

    GET /api/v1/feedback/{result_id}
    Request · Illustrative example · JSON
    {"result_id": "<result_id from your result>", "helpful": false, "reason": "missing_constraint"}
    POST /api/v1/feedback · Bash
    curl --fail-with-body --max-time 15 https://dilem.si/api/v1/feedback \
      -H "Authorization: Bearer ${DILEM_SESSION:?}" \
      -H "Content-Type: application/json" \
      --data-binary @feedback-input.json

    Send a message or report a response

    request_id: 32 lowercase hexadecimal characters. message: at least 5 non-whitespace characters, 4,000 maximum. kind=general for a message; kind=response for a report with the exact response attached. Email is optional. Keep identifier and payload stable; no automatic replay after ambiguous failure.

    Request · Illustrative example · JSON
    {
      "request_id": "<32 lowercase hex characters>",
      "kind": "general",
      "message": "<user-authorized message>",
      "email": "",
      "language": "fr",
      "source": "agent",
      "version": "unknown",
      "screen": "other",
      "response": null
    }
    POST /api/v1/user-feedback · Bash
    curl --fail-with-body --max-time 15 https://dilem.si/api/v1/user-feedback \
      -H "Authorization: Bearer ${DILEM_SESSION:?}" \
      -H "Content-Type: application/json" \
      --data-binary @user-feedback-input.json

    Credits

    One credit covers a dilemma through its first recommendation, including clarification questions. Any new calculation after that recommendation uses another credit.

    Use get_usage over MCP or GET /api/v1/usage over REST to check your remaining credits and when they renew.

    Limits come from the active policy, not a fixed value in this guide. PNG export and feedback use no dilemma credit, but retain technical and anti-abuse limits.

    Errors and recovery

    403: missing, invalid or expired session, rejected origin or forbidden cookies. 408/413/422: timeout, size or invalid input. 409: completed case. 429: quota, budget or capacity. 503: unavailable service. Also check the response type: pipeline errors can occur after admission. Never automatically replay a calculation after an ambiguous failure; Case-ID is not a calculation idempotency key.

    A disconnect may leave consumed work. Reading usage cannot reconstruct a lost response.

    Browser agents

    In a compatible browser, WebMCP lets your agent use the open page with your history and credits. Otherwise, use remote MCP or the API. Remote access accepts text; voice dictation remains available in the app.

    Read get_dilemma first. submit_dilemma sends a choice or answer; recommend_dilemma requests a recommendation without another question. Result actions use the visible case, not the remote token.

    WebMCP adds local image export with preview, votes and reports, plus list_saved_dilemmas and get_saved_dilemma for this browser’s history. The image URL expires when the preview closes. Neither that history nor browser cookies are shared with remote MCP.

    Technical reference

    OpenAPI schemas describe complete request and response bodies. The Markdown guide is an agent entry point; the catalog and Server Card expose MCP discovery.

    The service retains text exchanges for 30 days. Browser history stays on your device and is not shared with a remote agent.

    Privacy and providers

    Contact · [email protected]