Freebee Ads docs

Engineering docs

Support and incidents (2026-10-24)

Last updated Oct 24, 2026 · 8 sections

How advertisers reach us, who answers, and the numbered steps for the five things most likely to go wrong. Written for the person on duty, not for an engineer. Every page named here is in the ops portal at /ops unless it says otherwise.

How advertisers reach support

ChannelAddressStatusResponse time we promise
Emailsupport@freebee.media (alias to be created; forwards to the founder until there is a team)To doReply within one working day (Mon to Sat, 10:00 to 19:00 IST)
WhatsAppbusiness number to be added, shown on the Terms page and in the dashboard footerTo doSame working day for a message before 17:00
In the dashboardstatus badges, alert strips and rejection reasonsBuiltImmediate; this is where the answer appears first
Phone (screen down during a paid window)the ops on-duty number, given to the mall and to advertisers with a running campaignTo doPick up or call back within 30 minutes while malls are open

Rules for whoever answers:

  1. Reply from the shared alias, never from a personal address, so the thread survives staff changes.
  2. Every reply says what we found, what we did, and when the advertiser will hear from us next. No codes, no jargon.
  3. Anything about money (refund, credit, invoice) goes to the founder before it is promised.
  4. Log every incident in the incident sheet (date, screen, advertiser, what happened, what we did, make-good given). Until a tool exists, a shared spreadsheet is fine.

Severity and who is told

SeverityExampleWho is told, and when
S1A paid game window is dark; the site or API is down; a wallet or OTP outage during a campaignOn-duty person now; founder within 15 minutes; advertiser within 30 minutes if their window is affected
S2A screen offline outside a paid window; a wrong ad playing; a camera not countingOn-duty person now; founder same day; advertiser when the fix is in
S3A refusal appeal, an invoice question, a feature requestNormal support queue

Runbook 1: a screen is offline during a paid window

  1. Open Today (/ops). The alert strip names the screen and how long since its last check-in. A screen is "Not seen lately" after a few missed check-ins and "Offline" after that; the player checks in every 15 seconds while it runs.
  2. Open Devices (/ops/pair) and the screen's own page under Screens. Confirm: is the device still paired (status active), when was it last seen, and does the schedule for today show the booking?
  3. Call the mall contact for that screen. Ask them to check, in this order: power to the screen and the player box, the wifi light, and whether the player shows the pairing code (which means it lost its pairing) or a black screen.
  4. If the player shows a pairing code: pair it again from Devices with the same screen. Playback resumes within one schedule refresh (up to 5 minutes), and the queued play records upload when it reconnects.
  5. If it is a browser player that was closed: ask the mall to open the player address again in full screen. Until the native player ships, a closed tab is the most common cause.
  6. If power or network is the cause and the mall cannot fix it within 30 minutes, tell the affected advertisers: which screen, since when, and that missed plays are credited.
  7. Make-good rule: plays missed in a paid window are either added as extra days on the same or a similar screen, or the missed share is refunded. The advertiser chooses. The play record decides how many plays were missed; do not estimate.
  8. Write the incident up: cause, minutes down, plays missed, make-good given. Repeated outages on one screen go on the mall's monthly review.

Runbook 2: a creative is playing that should not

Examples: a complaint from the mall, a rights holder, or a shopper; an ad approved by mistake; a game with a wrong prize.

  1. Find the creative in Approvals (/ops/approvals), Approved column, and open its details. Confirm it is the one in question by its name, brand and preview.
  2. Pull it: open Bookings (/ops/bookings), find the booking that carries it, and cancel the booking item for the remaining dates. Each screen that carried it gets a new schedule version, and the player drops the ad on its next check-in (15 seconds) and refetches the loop.
  3. If the whole creative must go, not just one booking: reject it in Approvals with a plain reason. A rejected creative serves as idle in every slot it held, on every screen, from the next check-in.
  4. If the player does not change within two minutes, ask the mall to reload the player (browser refresh) and check Devices for its last check-in; a stale check-in means the device, not the schedule, is the problem (see Runbook 1).
  5. Tell the advertiser what was pulled and why, word for word as written in the rejection reason, and what they can do (fix and re-upload, or appeal per the content policy).
  6. If a game was pulled mid-campaign, check Wallet (/ops/wallet) for coupons already issued; coupons already in shoppers' phones stay valid and the advertiser must still honour them.
  7. Record the incident, including who approved the creative and whether the review checklist was ticked, so the review process can be tightened.

Runbook 3: wallet or OTP outage

Symptoms: shoppers at the kiosk cannot save a coupon; "Could not send the code" errors; complaints that no WhatsApp code arrives.

  1. Try it yourself: open /w on a phone, enter your own number, request a code. Note the exact error text.
  2. If the code request fails at once: the API is down or the WhatsApp provider is rejecting us. Check the backend health (<api>/health if present, or any page of the ops portal) and go to Runbook 4 if the API is down.
  3. If the code request succeeds but no message arrives: sign in to the AiSensy dashboard and check the freebee_otp campaign is live and the account has credits. A paused template or an empty balance is the usual cause. Top up or re-enable, then test again.
  4. If messages arrive but the code is refused: check the phone's clock is right and that the shopper is not past the 5 sends per hour or 5 attempts per code limit. Both limits reset on their own; ask them to wait an hour or request a fresh code.
  5. While the wallet is down, shoppers do not lose their wins: a win link stays valid for 48 hours. Tell the kiosk attendant to say "scan again later today; your prize is kept for 48 hours".
  6. When fixed, test a full claim (win, scan, OTP, coupon shows in /w) before calling it resolved. Log the outage window and the number of claims during it (from the Wallet page counts before and after).

Runbook 4: Railway (API) or Vercel (website) outage

  1. Check the status pages first: Railway at https://status.railway.com and Vercel at https://www.vercel-status.com. If either shows an incident, there is nothing to redeploy; tell the mall and any advertiser with a running window, and wait.
  2. Tell which side is down: the website loads but every page shows "Could not load" means the API (Railway); the website itself does not load means Vercel.
  3. API down and Railway status is green: open the Railway project respectful-adaptation, service dooh-platform, environment production, and read the deploy logs. A failed migration or a refused boot (for example a CORS setting the app rejects in production) shows there. Fix the variable or roll back to the previous deployment from the Deployments tab.
  4. Redeploy: push to main (Railway builds from the repo) or press Redeploy on the last good deployment. The Procfile runs alembic upgrade head then starts the API. See docs/DEPLOY.md section 1 for the variables the service needs.
  5. Website down and Vercel status is green: open the Vercel project, read the latest deployment's build log, and redeploy the previous production deployment from the Deployments list ("Promote to production"). See docs/DEPLOY.md section 2.
  6. Screens keep playing from their cached loop while the API is down and upload their queued play records afterwards; no plays are lost unless the player itself is restarted. The kiosk and the phone game do need the API, so a game window during an outage is an S1 (Runbook 1 make-good applies).
  7. After recovery, run the smoke test in docs/DEPLOY.md section 3 and confirm Today shows fresh check-ins from every screen.

Runbook 5: a data erasure request

The only personal data about shoppers is a wallet phone number, and the shopper can erase it without us.

  1. If a shopper asks in person or by message: tell them to open /w on their phone, sign in with that number, and press "Delete my number". That removes the hashed and the encrypted copies at once and withdraws their consent. Their coupons stay valid but are no longer linked to anyone.
  2. If they cannot do it themselves (lost phone, cannot receive the OTP): we cannot look a number up by sight, because we only hold a hash. Ask them to send the request from the number itself (WhatsApp or SMS to our support number) so we can match it. An engineer then runs the erase for that number against the database and confirms in writing. Log the request and the completion date; the DPDP Act expects a prompt answer and we promise 30 days at most in the privacy notice.
  3. To confirm an erasure worked: the Wallet page count of wallet users does not drop (erased rows are kept, anonymised), but signing in with that number again creates a fresh wallet with no coupons. That is the expected result.
  4. For an advertiser account: they write to support; we close the account, delete creatives not referenced by any booking, and keep booking and invoice records for the period tax law requires. Reply with what was deleted and what is kept and why.
  5. For a passer-by asking what the camera recorded: nothing identifying is stored, so there is nothing to erase. Send them the camera notice and the privacy notice's "Passers-by" section and offer to answer questions.
  6. Never put a phone number in an email subject, a ticket title, a chat message or a log. Refer to requests by date and the last four digits only.

Still to set up

  • Create the support@ alias and the WhatsApp business number; put both on the Terms page, the Privacy notice and the dashboard footer.
  • Pick an on-duty rota for mall opening hours and give the mall contact the number.
  • Uptime alerting for the API and the website (a free ping monitor on /health and / is enough to start).
  • A simple incident log (sheet) with the columns named above.
Support and incidents · Docs