IntegrAuth Academy
Identity, security and practical AI — free, from zero. Byte-sized lessons, real diagrams, hands-on labs, zero fluff. Two programs, each with its own exam and certificate.
English is hard? Your browser can translate this page into Tamil, Telugu, Kannada, Malayalam or Hindi. Tech words stay in English so you learn the real names.
How?
- Chrome on phone: ⋮ menu → Translate
- Chrome on computer: right-click → Translate to …
- Edge: the translate icon in the address bar
Your first AI feature
Priya's test script works. Now "Ask Acme" goes live for customers like Maya. Your goal: build an AI feature that is safe and fails well.
🧪 Interactive lab — enable JavaScript to play with this one.
- Keep your API key on your backend, never in the page.
- Take only the new message from the browser, never the history.
- Retry only what waiting can fix. Cap the tries and the time.
- Check why the model stopped before you show it.
Three boxes: browser, backend, model
The browser is the app on Maya's screen, with no secrets. Your backend is a server you run, a computer that runs your app's code. The model API is the provider's service.
Each call needs your API key. Anyone can read a web page's code, so a key there is public. Keep it on the backend (Using AI through an API).
The backend also checks who is signed in. It counts each user's messages. It keeps the system prompt on the server.
Your backend keeps the chat
A basic model API call starts fresh, with no memory of earlier calls. It is a stateless API. So your backend saves each chat and sends it each time. Think of a kirana shop's credit book. The shopkeeper keeps it, not the customer.
Never let the browser send the history. Someone can edit it and add a fake answer, like "Refund approved." The model treats it as real. Signing in does not stop this. So accept only the new message and a chat id this user may open.
When a call fails
Waiting can fix a busy provider or a rate limit. It never fixes a bad request or a used-up budget.
Now sort the jobs into the three boxes.
🧪 Interactive lab — enable JavaScript to play with this one.
Go deeper: which failures to retry
| What happened | Signals | Retry? |
|---|---|---|
| Your request, key or account is wrong | 400, 401, 402, 403, 404 | No. It fails the same way every time. Fix it. |
| Too many requests for your rate limit | 429, often with retry-after | Yes, after a wait. But some 429s mean a spend cap is used up. Some providers send 400 or 402 for that. Waiting will not fix it. |
| Provider trouble, or no answer | 500, 503 or 529 "overloaded", 504, a dropped connection | Yes, a few times. |
Each reply carries a status code, shown above. Wait longer after each try, with a small random extra. This is exponential backoff. Got a retry-after header? Wait that long. Fast retries can make things worse.
As of October 2026, the official Python SDKs from Anthropic and OpenAI retry some failures twice by default. Put your own 3-try loop around that, and one click can become 9 calls. So keep just one layer of retries.
Those SDKs can also wait up to 10 minutes for one request. That is too long for a person. So set a timeout for how long the stream may stay silent. Also set a total deadline. Base both on the wait times you measure. Then show a plain message and a "Try again" button.
Go deeper: streaming to the screen
In a product, streaming happens twice. Your backend gets the answer piece by piece. It passes each piece on to the browser. This often uses server-sent events.
Streaming changes how errors look. The "200 OK" status is sent before the first word. So a failure halfway arrives as an error event inside the stream. A stream that ends without its final "done" event was cut off. Show the answer as cut off, and offer "Regenerate". Don't add a retry onto the half answer Maya already read.
When Maya presses Stop, cancel the request to the provider too. In JavaScript, you can use an AbortController.
Go deeper: why the model stopped
Each response says why the model stopped writing. This is the stop reason. Check it before you show the answer. The names differ by provider. The cases are the same:
- Finished: show the answer.
- Hit the output limit, like
max_tokens: the answer is cut off. Say so, or offer "Continue". - Wants a tool: your code must run it and reply (Tool calling and structured output).
- Declined or blocked: show a clear message, not an empty bubble.
max_tokens is a ceiling, not a target. Set it too low, and answers get cut off. On many reasoning models, hidden thinking counts against it too.
Go deeper: what one request costs
Each response has a usage part with its token counts. Multiply them by your prices. Say input costs ₹240 and output ₹1,200 per million tokens. Then 2,500 tokens in and 400 out cost about ₹1.08. That is small, until one account sends ten thousand an hour. Then it is ₹10,800.
Some providers can store the chat for you, by id. You still pay for the old turns. Keep that id on your backend.
So log usage for every call, with the user, the feature and the model. Give each user a quota. Set a spend alert and a hard limit. More in Ship safely.
A demo always looks fine. Before launch, break it on purpose. Try a wrong key and a burst of requests. Treat what users type as untrusted (Prompt injection).