Watch the explanation. Practice the skill.

AI API requests and safe response handling

Translate a supported synthetic request and inspect text, usage and completion status. Distinguish simulated permanent and transient failures, and state live recovery limits. Record the actual runtime, fixture revision and verification result; identify the SDK/model evidence required for live reproduction.

Complete tutorial11:41

Captions appear here during playback.

AI API requests and safe response handling

Translate a supported synthetic request and inspect text, usage and completion status. Distinguish simulated permanent and transient failures, and state live recovery limits. Record the actual runtime, fixture revision and verification result; identify the SDK/model evidence required for live reproduction.

Download transcriptOpen video file

Local synthetic cases; independently reviewed narration. Automated screen capture and actual isolated fixture replay. No live provider compatibility or learning-effect claim. · Reviewed 2026-10-06. Microsoft Mark · locally synthesized. On a small screen, use fullscreen for diagram details or read the transcript.

Read the descriptive transcript

0:00 · Outcome and preparation

In this lesson, you will translate a bounded request, read its text, status and usage, and decide whether a result is ready for the next step. You will also reject an unsupported feature before a request is created and explain how permanent and transient failures differ. You need basic Python functions, environment variables and exceptions from the previous lesson. The required practice runs locally with Python and the standard library. It needs no keys, account, paid service or operational data. If Python is unavailable, trace the fixtures on paper and label execution unverified. We will demonstrate a provider-neutral contract. It is a teaching simulation, not the schema of a real provider. The page retains dated OpenAI and Anthropic examples, but they must be checked against the chosen SDK and model before any separately authorized live use. A local test pass does not prove an API round trip or a model's quality.

What appears on screen

Your local contract: Bounded request → provisional text → final status → inspect result Preparation: Python standard library, no keys/accounts/operational data. Local simulation, not a real provider schema. Test pass ≠ API compatibility or model quality.

1:05 · Define the bounded request

An API is an interface your code calls. For a generation task, specify the input and instructions, the supported features you need, an output bound and what your application expects back. Do not begin by assuming every provider or model supports the same options. Our fictional request asks for a short proposal from supplied logistics facts. It is a drafting request, not permission to send messages or change a system. Our simulated capability declaration supports streaming but does not support reasoning controls or schema output. Requesting an unsupported feature must fail before creation of the request. Tokens are units used by a model's tokenizer, not a guaranteed number of English words. A token limit bounds generation according to the endpoint's rules; it does not guarantee a complete or correct answer. The exact live fields and capabilities belong in the versioned reference. Our request contains only allowed fields. A feature typed into a generic dictionary is not automatically available. Watch `validate_request` return a clear error for an unsupported request before the reducer processes any response fixture. **Action:** Run the worked example with the unsupported capability fixture. Display validation error and no response processing.

What appears on screen

Open fixtures.json: { "capabilities": { "stream": true, "reasoning": false, "schema": false }, "request": { "input": "Fictional R1 logistics proposal; no savings measured", "max_output_tokens": 128, "stream": true } } Run python worked-example.py unsupported: request_rejected: Unsupported required capability: schema response_processed: false Observed capability rejection: Required schema unsupported No response processed Validation occurs before request creation.

2:33 · Map provider differences without guessing

Different APIs organize requests and responses differently. The lesson's dated examples place OpenAI Responses instructions and input in their respective fields, and Anthropic Messages system instructions separately from message content. These are illustrative reference examples, not the local fixture format. Check the actual version before implementation. An adapter translates a supported request into that interface and maps the returned fields to your application's contract. Preserve the request ID, text, terminal status, refusal information and known or unknown usage. Do not select behavior only by provider name or by whether the text is empty. If a feature is unsupported, reject it explicitly or choose a documented alternative. Do not silently drop it and claim equivalent behavior. History must be deliberately supplied or managed by the application according to the chosen interface. Neither a stronger model nor a chat subscription establishes API access, credit or permission to use real data. Our existing B3 offline pack lets you practice this mapping. Its Messages adapter is deliberately unfinished. Later you will implement it, compare against the worked example only after your attempt, and record what its tests do and do not establish.

What appears on screen

Dated provider reference: Responses-style: instructions + input Messages-style: system + messages Illustrative mappings; no SDK calls. Application adapter result: Request ID, text, terminal status, refusal, usage Preserve UNKNOWN usage Reject unsupported feature explicitly B3 learner starter: Messages adapter intentionally unfinished. Implement after your attempt. A chat subscription does not establish API access, credit or permission.

4:00 · Read a complete simulated response

Now run the complete fixture. These events come from a local JSON file. Nothing contacts a model. The reducer receives text chunks and a completed event. It preserves the fixture ID and usage. The final status is complete and no refusal occurred, so our application may pass this result to its next inspection step. That is transport-contract readiness, not factual correctness. Before using the draft, compare its claims with the supplied source. A complete response can still invent a result. Today's fixture uses authored text; its passing status does not measure model reliability. Notice that usage may be absent. Unknown usage should remain null or explicitly unknown; it must not become zero. Zero is a numerical claim. We record only safe metadata here, not raw keys or sensitive prompt content.

What appears on screen

Open worked-example.py: validate_request(request, capabilities) result = reduce_events(events) release = should_release(result) No network imports. Local fixtures only. Run python worked-example.py complete: request_id: mock-01 text: "We propose a two-week trial. Savings remain unknown." status: complete refusal: false usage: {"input_tokens":31,"output_tokens":12} release: true scope: local synthetic fixture only Inspect the complete draft: Transport-contract readiness only. Compare claims against supplied source. Unknown usage remains null, not zero.

5:00 · Streaming and the misleading success

Streaming lets an interface show text before the response has completed. That can make progress visible, but chunks are provisional. The cancelled fixture contains readable text and then stops with cancellation. The reducer reports partial, preserves the request ID and leaves missing usage unknown. It does not release the text as a finished result. Here is the mistake we want to catch: “If there is any text, the call succeeded.” Our starter deliberately makes that decision. It would accept the cancelled fixture because the text is nonempty. Predict what happens with a refusal containing explanatory text. A refusal is also not a completed answer for the requested task. The same shortcut would accept it. Repair the decision by checking the terminal status and refusal flag, not merely the string. For this local contract, release requires complete status and no refusal. The code also rejects unknown or contradictory event sequences. A stream that ends without a terminal event stays partial. An error after completion is invalid in our fixture contract. These are local validation rules, not a claim that every SDK emits the same event sequence. **Action:** Show the worked release condition and rerun cancelled, refusal, incomplete and complete. Demonstrate rechecking a repaired rule, not just displaying it.

What appears on screen

Run python worked-example.py cancelled: request_id: mock-02 text: "We propose a trial" status: partial refusal: false usage: null release: false scope: local synthetic fixture only Run python starter.py refusal: DELIBERATELY FLAWED before repair request_id: mock-04 text: "I cannot fulfill that request." status: refused refusal: true usage: null release: true scope: local synthetic fixture only Edit isolated starter.py: BEFORE: return bool(result["text"]) AFTER, equivalent multiline formatting: return ( result["status"] == "complete" and result["refusal"] is False ) Original learner starter remains unfinished. Rerun repaired guard: cancelled: status=partial, refusal=false, release=false, usage=null refusal: status=refused, refusal=true, release=false, usage=null incomplete: status=partial, refusal=false, release=false, usage={"input_tokens":31,"output_tokens":128} complete: status=complete, refusal=false, release=true, usage={"input_tokens":31,"output_tokens":12}

6:31 · Failures and bounded recovery

Permanent authentication, permission or invalid-request failures need correction. Repeating the same broken request is not a repair. Some connection, rate-limit or server failures may be transient, but retry policies depend on the endpoint, SDK and operation. Check the installed version and choose one owner for retries. Do not wrap an SDK retry loop in another loop without understanding how the attempts multiply. A timeout per attempt is different from an overall deadline. A budget caps retry attempts and cost exposure; it does not establish that a real network deadline was enforced. Also distinguish generating a draft from a consequential downstream action. Retrying text generation is not permission to resend a message, make a purchase or repeat a transaction. Our lab does none of those actions. A cancelled or ambiguous action needs its own safe recovery policy. Use the existing B3 pack to inspect permanent failures, transient recovery and simulated budget/deadline failures. Those tests simulate policy decisions; they do not establish live transport behavior. If you cannot explain the retry owner and stopping rule, do not claim your application is safely bounded.

What appears on screen

Failure decisions: Authentication / permission / invalid request → fix cause Selected transient failure → bounded retry if safe Ambiguous downstream action → separate recovery policy Retry boundaries: One retry owner Per-attempt timeout ≠ overall deadline Simulated budget ≠ enforced HTTP deadline No transaction or sending permission B3 observed worked test summary: Ran 15 tests in 0.001s OK

7:54 · Reproduce and inspect the evidence

Run the supplied worked-example tests locally. Record the Python version, fixture revision, command and observed output. Do not copy a passing result from the page and call it your execution. For the existing B3 pack, read the README first. Run its tests against the starter to observe the unfinished adapter. After your attempt, set `LAB_IMPL` to `worked_example` and rerun to inspect the supplied solution. Clear that setting before checking your starter again. Keep your original failure, correction and recheck separate. Our supplemental streaming fixtures exercise a smaller release decision. They complement the existing adapter practice; they do not replace the full B3 tests. Passing both still leaves live SDK integration, actual provider capabilities, transport timing and factual output quality unverified. If you choose live practice in the future, use separately authorized data and access, verify the model and SDK, pricing and limits, and record the actual request and response safely. This tutorial does not ask you to create an account or run a paid call. A storage option in an API request is not a blanket promise of zero retention; review the current provider policy and organizational approval.

What appears on screen

Worked-example test summary: Python 3.14.2 Ran 11 tests in 0.002s OK Revision: tutorial-pilot-2026-10-06 Observe unfinished B3 adapter: NotImplementedError: Implement the messages mapping using the contract and fixtures NotImplementedError: Implement the messages mapping using the contract and fixtures NotImplementedError: Implement the messages mapping using the contract and fixtures NotImplementedError: Implement the messages mapping using the contract and fixtures NotImplementedError: Implement the messages mapping using the contract and fixtures NotImplementedError: Implement the messages mapping using the contract and fixtures NotImplementedError: Implement the messages mapping using the contract and fixtures Ran 15 tests in 0.004s FAILED (errors=7) Inspect supplied solution after attempt: Ran 15 tests in 0.001s OK Clear LAB_IMPL before checking starter. Evidence and limits: Record fixture/runtime, command, observed output, correction. No live SDK compatibility, provider capabilities, transport timing or factual quality proved.

9:21 · Independent practice

Pause before the solution chapter. First, repair the starter's release decision. It should preserve the reducer's IDs, status and unknown usage while refusing partial, failed, refused or invalid results. Add an explanation of why nonempty text is insufficient. Second, use the B3 pack to implement the unfinished adapter without changing expected tests. Independently reject an unsupported capability before request creation and write a migration note explaining what would change if a capability became available. Keep your code, first failure, corrected result, version information and limitation note. Do not edit expected answers to make the tests green. If you only trace on paper, label that honestly and predict each final status and release decision.

What appears on screen

Independent practice · pause: Repair should_release in your own copy. Preserve ID / status / unknown usage. Reject partial, failed, refused, invalid. B3: implement unfinished adapter; keep expected tests. Your evidence record: First failure → correction → recheck Version + fixture revision + limitation Reject unsupported feature before request creation Paper trace? Label execution unverified.

10:15 · Feedback and transfer

If cancelled text was released, your decision used appearance instead of completion status. If a refusal was released, check both the status and refusal flag. If missing usage became zero, restore unknown. If unsupported capabilities reached processing, move validation before creation. Recheck the full fixture set after the repair. The completed rule in this teaching contract is complete status and no refusal. That is one guard in a larger workflow. A real adapter must also handle the actual SDK's events and errors, validate required structured output and inspect the content's factual support. Our small reducer is not production code or a comprehensive security boundary. Now explain an unfamiliar case without looking at the code: text arrives, no terminal event arrives, and the connection ends. What should your application report? What remains unknown? What would you check before doing anything with the text? You have practiced the transferable distinction between provisional output and an inspected result. Reviewing the lesson does not certify a live integration. Save the evidence record and move to the next lesson when you can explain your guard and its limits. Use the dated provider references when you are ready for separately authorized integration.

What appears on screen

Feedback · solution ahead: Nonempty text is insufficient. Check complete status AND no refusal. Restore unknown usage; validate features first. Observed repair test summary: Before repair: failure expected Ran 2 tests in 0.009s FAILED (failures=6) After isolated repair: Ran 2 tests in 0.001s OK Transfer the guard: Text arrives; no terminal event; connection ends. Report partial; usage remains unknown if absent. Inspect support and permissions before any action.

Watching explains the example. Complete the lesson practice to check what you can do. Explore all visual lessons →