The problem nobody builds for
Every tool in the creator-tooling space optimizes the top of the funnel — clips, thumbnails, titles, SEO. Almost nothing protects the part where creators actually get paid.
A brand deal is a contract with a dozen obligations scattered across four pages of legal prose. Verbal mention inside 90 seconds. Affiliate link in the first three lines of the description. Discount code, verbally and in text. Disclosure before the endorsement, not after it. Miss one and the brand can withhold payment. Miss the disclosure one and it stops being a money problem and becomes an FTC problem.
Creators check this by re-reading a PDF at 2am before hitting publish. That is the pain point DealCheck automates.
What it does
Paste the brand contract on the left. Paste your video script, description, and on-screen text on the right. DealCheck runs one audit and returns:
- Every obligation extracted from the contract, each one carrying the verbatim clause it came from
- A status per obligation: met, partial, missing, or unverifiable
- A dedicated FTC disclosure check, judged against the actual standard — clear, conspicuous, and placed before the audience encounters the endorsement
- A copy-paste fix for every failure, not advice
- A publish verdict: cleared, caution, or blocked
The mechanism that makes it trustworthy
The interesting constraint is not extraction — it is refusing to extract.
An obligation only appears in the report if the model can attach a verbatim quote from the contract to it, and that quote renders in monospace directly on the card. If it cannot quote the clause, the obligation does not exist. This makes hallucinated obligations structurally impossible to display: the proof is part of the render, not a footnote.
The second constraint is the "unverifiable" status. A naive version marks "product visible on screen for 45 seconds" as failed, because it cannot see the video. That is a false negative that trains creators to ignore the tool. DealCheck separates "I checked and it is missing" from "I cannot check this from text," and only the first kind blocks a publish.
Third, contract facts and content obligations are kept apart. Payment terms, usage rights, and exclusivity windows surface in the deal summary. Only things verifiable against the creator's own content become checkable obligations. Without that separation the model dumps every clause into the checklist and the report becomes noise.
How I built it
React, TypeScript, and Tailwind, single page, no backend, no auth, no database. All state lives in hooks.
One Gemini call per audit — gemini-2.5-flash with responseMimeType set to application/json and a strict responseSchema. Because the output shape is guaranteed, the frontend has zero defensive parsing and no fallback rendering for when the response comes back as prose instead of structured data. The schema does the work that error handling would otherwise do.
The state machine is a discriminated union across idle, loading, error, and success, so every state is explicitly designed. Failed calls render a bordered retry card, never an alert and never a silent failure.
Challenges
Getting the model to be strict without being useless. Early versions flagged Keychron as an exclusivity breach in a headphone sponsorship because the word "competing brand" pattern-matched to any product name. The fix was scoping exclusivity checks to the category named in the clause itself.
Calibrating the disclosure check was the other one. "#ad exists somewhere in the description" is trivially satisfiable and worthless. Encoding the actual placement standard — before the endorsement, not buried under a timestamp block — is what makes the check mean something.
What I learned
Structured output is not a formatting convenience, it is the architecture. Once the response shape is guaranteed, roughly a third of the code you would otherwise write simply stops being necessary.
What's next
Reading the contract straight from a PDF, pulling the live description via the YouTube Data API so the audit runs against what actually shipped, and a re-audit after publish to catch descriptions that get edited later.
Built With
- gemini-2.5-flash
- google-gemini
- react
- tailwindcss
- typescript
- vite
Log in or sign up for Devpost to join the conversation.