Acting

Moderation

Moderation

birdclaw maintains account-scoped block and mute lists locally. Every action records the local intent first, then attempts the live transport. If the live transport fails, the local row stays and a future re-sync reconciles.

All commands accept --account <id> to pick an account when more than one is configured.

#Blocks

2 blocks list 0 acct_primary 1
2 blocks add @amelia 0 acct_primary 1
2 blocks remove @amelia 0 acct_primary 1
2 blocks record @amelia 0 acct_primary 1
2 blocks sync 0 acct_primary 1
2 blocks import ~/triage/blocklist.txt 0 acct_primary 1

#blocks add

Add a local block entry and attempt a live block write.

Accepts a handle (amelia), @handle, Twitter URL, local profile id, or numeric Twitter user id.

Live transport order:

  1. xurl — when resolvable. Twitter often rejects pure OAuth2 block writes.
  2. bird — cookie-backed fallback.
  3. xweb — last-resort web cookie session for auto mode.

When all three fail, the local block is still recorded so the web UI hides the account immediately. A later blocks sync will retry.

#blocks remove

Mirror of blocks add. Removes the local block and attempts a live unblock through the same transport ladder.

#blocks record

2 blocks record @amelia 0 acct_primary 1

Records a known-good remote block locally without issuing another live write. Useful when:

  • a block was made on twitter.com directly and you want birdclaw to know about it
  • a previous blocks add succeeded remotely but failed to update the local row

#blocks sync

Slow / manual remote reconciliation. Walks the live block list (when transport allows) and reconciles missing local rows. Not for hot cron loops.

#blocks import

Bulk import a blocklist file. Reads newline-delimited handles, IDs, or Twitter URLs.

2 blocks import ~/triage/blocklist.txt 0 acct_primary 1

Tolerates:

  • blank lines
  • # comments
  • markdown bullets like - @handle
  • Twitter URLs and numeric IDs

Example file:

# crypto / AI slop
@jpctan
@SystemDaddyAi
- @Pepe202579 memecoin bait
https://x.com/someone/status/2030857479001960633?s=20

Per-entry success/failure shows up in the --json output so you can grep failures and retry.

#ban / unban (shorthand)

3 ban @amelia 0 acct_primary 1 auto 2
3 unban @amelia 0 acct_primary 1 4 2

ban / unban are aliases for blocks add / blocks remove with one extra knob: --transport.

  • --transport auto — try bird first, then xurl, then xweb cookie-backed (the safest default for OAuth2-rejected accounts)
  • --transport bird — force bird
  • --transport xurl — force xurl; verifies through bird status before mutating SQLite

#Mutes

2 mutes list 0 acct_primary 1
3 mute @amelia 0 acct_primary 1 4 2
3 unmute @amelia 0 acct_primary 1 auto 2
2 mutes record @amelia 0 acct_primary 1

Same model as blocks, with one resolution detail: mute and unmute prefer bird user --json for target resolution before falling back to xurl /2/users. This is faster and avoids burning an xurl user lookup for accounts you can already see in bird.

mutes record stores a known-good remote mute locally without issuing another live write.

#Auto-fallback in the wild

OAuth2 block writes are the most common failure case. Twitter intermittently rejects them with no recoverable error code. For that reason:

  • auto is the default everywhere
  • auto includes the xweb cookie fallback for blocks
  • forced xurl writes still verify through bird status before sqlite changes
  • failed live writes never leave the local DB in an inconsistent state — either the local row reflects the live state or it is rolled back

If your account chronically rejects OAuth2 blocks, just set:

{
  0 {
    1 2
  }
}

and stop thinking about it.

#Web UI

The Blocks lane shows the local list, lets you bulk-import from a file, and exposes per-account scoping. Mutes are surfaced inline on profile rows in the Mentions and DMs lanes — adding a mute from there feeds the same mutes table the CLI uses.

#See also

  • Configurationactions.transport precedence
  • Mentions — borderline-AI triage before blocking
  • Inbox — low-signal heuristic scoring