1. Install the single-file CLI
The CLI requires a current Node.js runtime. This fail-closed installer pins and verifies the release SHA-256 with Node before making it executable. Keep it in the working directory or move it into a user-owned bin directory.
set -eu
SFB_CLI_FILE='submitforbacklinks-1.1.0.mjs'
SFB_CLI_SHA256='669e7894aa7c1914d9b2e432aa05a0be87c33dc2b68edbcc6601880e385526ee'
curl -fsSL 'https://submitforbacklinks.com/downloads/submitforbacklinks/1.1.0' -o "$SFB_CLI_FILE"
node - "$SFB_CLI_FILE" "$SFB_CLI_SHA256" <<'SFB_VERIFY'
const { createHash } = require("node:crypto");
const { readFileSync } = require("node:fs");
const [file, expected] = process.argv.slice(2);
const actual = createHash("sha256").update(readFileSync(file)).digest("hex");
if (!/^[a-f0-9]{64}$/.test(expected) || actual !== expected) {
console.error("Checksum verification failed.");
process.exit(1);
}
console.log(file + ": checksum verified");
SFB_VERIFY
chmod +x "$SFB_CLI_FILE"
ln -sf "$SFB_CLI_FILE" submitforbacklinks
./submitforbacklinks --version2. Verify the product domain in the terminal
Setup asks for a contact email for submission notices, not an email code. Publish the exact short-lived .well-known challenge on the product domain. The CLI then stores its credential in a user-owned config file with 0600 permissions. There is no Settings visit, copied key, password, or .env file.
./submitforbacklinks setup https://yourproduct.com \
--email [email protected]
# Add and deploy the exact .well-known file returned above, then:
./submitforbacklinks setup --verifyHow an agent should help
If the agent can edit and deploy the product repository, it should add the returned proof file, deploy it, run verification, and offer to remove the proof afterward. Otherwise it should ask the owner only to publish that exact file.
3. Scan and review the product site
Scanning is stateless: it does not create a listing, reserve the domain, or guarantee that draft creation will succeed. Save its output, then inspect and correct the proposed content while keeping source URLs, warnings, and confidence available as review context.
./submitforbacklinks scan https://yourproduct.com --pretty > scan.json4. Save a draft
Pass the reviewed scan file so the saved draft uses the content you inspected instead of starting a separate unseen scan. Generate and store a new UUID for this distinct mutation. Reuse that exact key only if the identical request must be retried. A draft is owner-scoped and does not enter editorial review.
# Inspect and edit scan.json before creating anything.
export SFB_DRAFT_KEY="$(node -e 'console.log(crypto.randomUUID())')"
./submitforbacklinks draft https://yourproduct.com \
--from-scan scan.json \
--idempotency-key "$SFB_DRAFT_KEY"5. Review the saved state and correct it if needed
Retrieve the submission ID returned by draft, save the exact server state, and present its submission fields to the owner. If any field needs correction, edit reviewed-status.json, generate and store a new UUID for the update, update the draft, and retrieve it again. Update sends the complete nine-field listing set rather than a partial patch. A --from-status file is bound to its submission ID. You may instead use --from-scan, but the two options are mutually exclusive. Every CLI mutation using --from-scan validates its source hostname against the submitted website; update performs an owner-scoped status preflight and therefore needs submissions:read as well as submissions:write.
./submitforbacklinks status 00000000-0000-4000-8000-000000000000 --pretty > reviewed-status.jsonexport SFB_UPDATE_KEY="$(node -e 'console.log(crypto.randomUUID())')"
./submitforbacklinks update 00000000-0000-4000-8000-000000000000 \
--from-status reviewed-status.json \
--idempotency-key "$SFB_UPDATE_KEY"6. Finalize only after explicit review
Generate and store a new UUID for finalization. All four confirmation flags are required; the CLI will not silently infer them. Add --week YYYY-MM-DD to request an available launch week, or omit it to use the next available week.
export SFB_FINALIZE_KEY="$(node -e 'console.log(crypto.randomUUID())')"
./submitforbacklinks finalize 00000000-0000-4000-8000-000000000000 \
--idempotency-key "$SFB_FINALIZE_KEY" \
--confirm-terms \
--confirm-badge \
--confirm-representative \
--confirm-reviewedWhat the four flags mean
You accept the terms and guidelines, understand the free badge requirement, are authorized to represent the product, and have reviewed the generated listing content for accuracy.
7. Track editorial status
Use the submission ID returned by draft or submit. Detail responses are restricted to the API-key owner.
./submitforbacklinks status 00000000-0000-4000-8000-000000000000Optional: edit from the dashboard too
Claiming is not required for terminal submission or editing. The command returns a 15-minute, one-use link. Open it and sign in with Google or an existing account; the terminal credential keeps working.
# Optional: connect the terminal-owned submissions to the web dashboard.
./submitforbacklinks claimOptional media stays in the browser dashboard
A logo and up to three screenshots are optional. Agent API v1 and the CLI do not upload or replace media.
The owner can add or manage media from the signed-in browser dashboard.
REST-only alternative
The CLI is optional. This minimal request creates a server-scanned draft. Retrieve and review the actual saved draft before correcting or finalizing it. Use the same bearer token and a caller-generated UUID as the idempotency key.
export SFB_CURL_DRAFT_KEY="$(node -e 'console.log(crypto.randomUUID())')"
curl --fail-with-body --request POST \
https://submitforbacklinks.com/api/v1/agent/submissions \
--header "Authorization: Bearer ${SUBMITFORBACKLINKS_API_KEY}" \
--header "Idempotency-Key: ${SFB_CURL_DRAFT_KEY}" \
--header "Content-Type: application/json" \
--data '{
"websiteUrl": "https://yourproduct.com",
"action": "draft",
"listingType": "FREE"
}'