MainSDK
Search⌘K
How-to

Moderate user content

Take reports, hold uploads until a pre-screen clears them, decide with a statement of reasons, take appeals and export the transparency report.

Building for 0.4

Status Status is where the work is: Planned (in a milestone, not started), Building (tickets in progress), Preview (usable, may change), then the stability it ships at.

Stability The promise an interface ships with.

  • Stable Follows semantic versioning; breaking changes need a new major, 12 months of overlap and a codemod.
  • Beta Usable in production; may change before it becomes stable.
  • Experimental May change or go away; needs an explicit opt-in in main.yaml.
Stability levels
Updated 2026-10-28

You will take a report, decide it with a ground, and export the statements for a period. It takes about 20 minutes.

You need

  • A MainSDK app where people post content others see.
  • A reviewer role with the moderate.review permission.

1. Turn it on

main.yaml
moderate:
  hold: { files: true, media: true, max: 24h }
  reports: { per-user: 20/hour }
  appeals: { window: 6mo }

Uploads and media outputs stay held until the pre-screen clears them, and go to a person after 24 hours.

2. Take a report

app/report.ts
import { moderate } from "mainsdk/experimental/moderate";

declare const post: { id: string };
declare const user: { id: string };

await moderate.report({ target: { kind: "post", id: post.id }, reason: "harassment", by: user });

3. Decide it

app/review.ts
import { moderate } from "mainsdk/experimental/moderate";

declare const caseId: string;
declare const reviewer: { id: string };

await moderate.decide(caseId, { action: "remove", ground: { kind: "terms", ref: "terms" }, facts: "Targeted insults", by: reviewer });

Any action except none needs a ground and facts. The person affected can moderate.appeal(decisionId, { by }) inside the window, and a different reviewer resolves it with moderate.resolve.

4. Export the records

bash
npx mainsdk moderate statements --tenant acme --from 2026-01-01 --to 2026-03-31 --out statements.json
npx mainsdk moderate transparency --tenant acme --from 2026-01-01 --to 2026-03-31 --json

statements writes the statements of reasons in the dsa-tdb format. transparency prints counts of reports, decisions and appeals. Both read the tenant's own region.

Check that it works

  • moderate.statement(decisionId) returns a statement for the decision you made.
  • A second appeal on the same decision is refused.

Next

Was this page helpful?

↑↓ moveEnter openEsc close

Not decided yet