Internal campaign management for the Nineten Clients platform — run any client's campaigns, content, trials, and credentials from Claude. Acts on behalf of a client via company_profile_id.
MCP Endpoint URL
…/api/mcp
Login: …/api/login · auth: Bearer <session token>
How to Connect (Claude)
In Claude, click your name (bottom left), then go to Settings → Connectors → + Add → Add custom connector
Name it Nineten Admin, paste the endpoint URL above, click Continue, then sign in with your staff email + password
Done — every action is audited under your email
Available Tools 344
Clients
admin_list_clients / admin_get_clientList all clients or pull one client's 360 (profile + services + sending identities).
admin_create_client / admin_update_clientCreate or edit a client (company_profile).
admin_set_account_statusMove a client through lead → trial → active → paused → churned.
admin_detect_mailbox_serversWhich mail servers an address uses, and which kind of password it needs. Read-only.
admin_connect_mailbox_directConnect a client's inbox from their address + app password, with no link and no hosted form (portal form only).
admin_get_client_plan / admin_set_client_planSee or switch a client's Email plan (Full or Nineten Email Basic), with what the switch would hit.
admin_get_telegram_invite / admin_rotate_telegram_inviteGet the client's live Telegram-alerts invite link + QR (lazily mints one only if the current one expired), or force-replace it. Rotate is destructive — confirm.
admin_list_telegram_subscribers / admin_remove_telegram_subscriberSee who is receiving a client's Telegram alerts, and remove one. Remove is destructive — confirm.
admin_turn_on_telegram_questions / admin_turn_off_telegram_questionsSwitch the day-after "What happened next?" question on or off for a client's Telegram alerts. On is destructive: confirm.
admin_turn_on_found_digest / admin_turn_off_found_digestSwitch the weekday Telegram digest of the leads the lead finder found on or off for a client on an email trial. On is destructive: confirm.
Services & Sending Identity
admin_add_service / admin_set_service_stageManage email / social / seo / ai service state + stage per client.
admin_add_sending_identityAttach a per-client Mailgun from-address + domain (assumes the domain is already registered on Mailgun).
admin_register_domainRegister a client's domain on Mailgun (US, auto-DKIM, shared IP) + create the sending identity. Returns DKIM/SPF/CNAME records AND an auto-built client-share xlsx (SPF merged + Nineten DMARC). Rate-limited; alerts chuan@/cs.chong@ on success. Destructive — confirm.
admin_setup_domain_eventsPoint all 6 Mailgun events (opened/clicked/complained/unsubscribed/permanent_fail/temporary_fail) at the engine webhook and enable the domain-level unsubscribe footer — the one-press fix for a client showing sends but zero opens, or missing an opt-out. Additive and idempotent, safe to call twice.
admin_get_domain_dns_excelRe-fetch the client-share DNS xlsx for an already-registered domain (SPF auto-merged via DoH lookup + Nineten DMARC). Read-only.
Credentials & Access
admin_issue_login_key / admin_list_login_keys / admin_revoke_login_keyIssue, list, and revoke a client's MCP login keys.
admin_set_provider_key / admin_list_providersSet (Vault) and list a client's Apollo / Apify / ZeroBounce keys. Set is destructive — confirm.
Web Analytics
admin_set_tracker / admin_get_tracker_snippetEnable Nineten's own first-party website tracker for a client (real-time, prospect-resolved page visits) and get the ready-to-paste snippet for their site's <head>. Stop collection with admin_disable_tracker; reissue a leaked key with admin_rotate_tracker_key.
admin_get_visitor_id / admin_set_visitor_id / admin_turn_off_visitor_idVisitor identification: load a provider's script (Snitcher first) on a client's website through NineTen's tracker, so the client installs nothing more. Needs website tracking on. Get reads the setting, its status and the workspaces the client's stored Snitcher token opens. Set checks the picked workspace against that token, then turns it on or changes it; the script loads only on the workspace website's domain, its subdomains and the extra domains you add. Turn off stops it within about a minute and keeps the saved choice. Set and turn off are Destructive: they change what runs on the client's website, so confirm. The companies it identifies also come into NineTen as website companies.
admin_get_website_companies / admin_set_website_sync / admin_set_website_company_hiddenWebsite companies: the companies Snitcher identifies on a client's website, read hourly into NineTen; in On one contact at each is found with the client's own Snitcher credits and saved as a lead no campaign adds by itself. Get reads the companies (skipped ones and dry-run picks too) and the settings. Set sync picks Off, Dry run or On, the cap per Snitcher cycle and the reserve. Hide is Not for us; hidden false puts it back. Both writes are Destructive: confirm. Dashboard: the company window, Website Tracking.
admin_website_people_preview / admin_website_people_confirmMore people at a website company, on the client's own Apollo key: preview is a free search of the company's own website (verified emails, who is known already, the cost of one person); confirm adds up to 10, looks up their emails at once and checks them on the client's ZeroBounce key (saved unverified with no key, or when the check is still unanswered on the last try), and saves them as leads no campaign adds by itself. Destructive: confirm.
admin_get_tracking_overview / admin_get_tracked_pages / admin_get_page_visitorsRead the tracker: per-client rollup (totals, top pages, device/country breakdowns, daily series), the tracked-pages table (views + prospect counts per page), and who visited a given page (the audience for page-targeted campaigns).
admin_list_sessions / admin_get_session_detailBrowse a client's visit sessions (who, entry → exit, pageviews, duration, device, utm; filterable to one page) and drill into a session's click-by-click journey.
admin_get_engagement_logAudit a client's email open/click counting — every Mailgun event scored human vs bot (verdict + 0–100 score + why); only human-verdict events count into the metrics.
Social Publishing (Zernio)
admin_set_zernio_key / admin_get_social_accountConnect a client's own Zernio account (key tested live before saving, platforms cached, publish/fail webhook auto-registered) and read the connection state. Repair a missing webhook with admin_register_social_webhook (uses the stored key). Kill switch: admin_set_social_enabled; remove credentials: admin_disconnect_social.
admin_connect_social_account / admin_disconnect_social_accountManage the individual channels inside a client's Zernio account. Connect returns an OAuth link to authorize a new Instagram/Facebook/etc. on the platform's own site (then refresh to pull it in); disconnect removes one channel by its accountId (the key + other channels stay). Destructive disconnect — confirm.
admin_create_social_post / admin_approve_social_postDraft a post (caption + media + platforms + optional schedule), then approve to push it to Zernio — publishes to all the client's connected platforms at once; status streams back via webhook. Media is Zernio-hosted: pass a URL, or upload a file via admin_get_social_upload_url (presigned PUT, up to 5GB). Edit drafts with admin_update_social_post; cancel with admin_cancel_social_post.
admin_bulk_create_social_postsBulk-create a month of draft posts from the team's xlsx content calendar (Day/Topic/Caption/Hashtag/Drive link columns; empty cells ignored; Drive links auto-converted; Day N + start date → schedule). Dry-run preview first; everything lands as drafts. Dashboard: "Bulk upload" on the Social posts page.
admin_list_social_posts / admin_get_social_post / admin_list_social_eventsTrack every post's lifecycle (draft → scheduled → published/partial/failed, per-platform results) and the raw Zernio webhook stream.
admin_cancel_social_post / admin_delete_social_postCancel a post (soft — keeps the record) or permanently delete it; a scheduled post is taken off Zernio first, and nothing changes here unless Zernio confirms. Both destructive — confirm.
admin_list_zernio_accounts / admin_list_social_profilesZernio profile ownership. One Zernio account can serve several companies; a profile (the workspace holding the channels) belongs to exactly one company at a time. list_zernio_accounts is cross-client: which companies share an account. list_social_profiles is the staff view of one company's account: every profile with who owns it, whether it is unclaimed, and its channel count. Dashboard: the Profiles block and the "Shared Zernio accounts" panel on the Social posts page.
admin_claim_social_profile / admin_release_social_profileAssign an unclaimed Zernio profile to a client so its channels become theirs to publish to (first-come; a profile another company owns is refused and nothing changes), or hand one back so a neighbouring company on the same account can claim it. Release is destructive — confirm.
admin_set_calcom_key / admin_set_ai_key / admin_get_social_credentialsStore a client's Cal.com API key (powers the Phase-4 chatbot booking) and their own Claude/Anthropic BYOK key (admin_set_ai_key — the client's AI Training + reply features use it, else NineTen's shared key); both tested live before saving. Read the client's social-stack key state (last-4 only, never secrets). Remove with admin_disconnect_calcom / admin_disconnect_ai_key. Dashboard: the client modal's "API keys" section covers Apollo/Apify/ZeroBounce/Zernio/Cal.com/Claude in one place.
Trials
admin_start_email_trial / admin_run_trial_sweepProvision a 4-step Initial Outreach trial and sweep completed trials.
Reporting (read)
admin_get_prospects / admin_get_prospect_detail / admin_get_prospect_regions / admin_list_import_batchesQuery prospects (scoped or cross-client), pull a single 360, list the distinct region values (with counts) in a book, or list a client's upload batches with the live number of prospects in each.
admin_rename_import_batchCorrect a mistyped upload-batch name. A batch is labelled by its first chunk and later chunks never rename it, so this is the only way to change one. Label only — no prospect moves batch.
admin_get_engaged_prospectsWHO engaged — per-prospect opens/clicks roster for one campaign or one content (history-based, human-verified). Powers the "Engaged prospects" dashboard page and its exact-bucket drill-downs.
admin_list_contents / admin_get_content / admin_get_engine_statusBrowse content templates, read one in full, global engine snapshot.
Report Picks
admin_get_report_evidence / admin_set_report_picks / admin_clear_report_picksThe NineTen team's picks on a client's Report page: read what a sent campaign earned, preview the picks, publish them once staff approve, or take them off.
admin_clear_report_suggestionTake the AI's saved suggested campaign off one automatic group of a client's Report page, or off every group of one campaign with all_groups: true. The client can ask for a new one with Suggest a campaign. Destructive: confirm.
Campaign Ops
admin_import_prospects / admin_update_prospect / admin_enrollImport prospects; update one prospect (funnel status, campaign stage + field edits, suppress/reactivate); run tenant-scoped enrollment.
admin_prospect_delete_preflight / admin_delete_prospectPermanently delete one prospect. Preflight is read-only and counts what blocks it (send history, replies, queued sends, promotions); delete refuses unless all four are zero and cascades the prospect's enrollments. For anyone already emailed the answer is admin_update_prospect suppress:true (status 'removed', reversible). Delete is destructive — confirm. Dashboard: the prospect detail modal.
admin_upsert_content / admin_validate_content / admin_delete_contentWrite, validate, and delete email content for a client (delete refuses if linked or sent).
admin_score_contentAdvisory SpamAssassin spam-filter score (via Postmark) + plain-English reasons for a saved content or a raw draft. Never blocks. Dashboard: "Check spam score" in the content modal.
admin_get_attachment_upload_url / admin_add_attachment / admin_list_attachments / admin_delete_attachmentAttach files to a content; they auto-send with every drip + blast that uses it. Upload (browser → signed URL → Storage direct), list, and remove. Dashboard: the Attachments section in the content modal.
admin_test_send_contentSend a production-faithful preview of a content (rendered like a real send, with its attachments) to any email. Tracking off, writes nothing. Dashboard: "Send a test" in the content modal.
admin_preview_content / admin_set_letterheadSee an email exactly as it would be sent, without sending it; set the client's email letterhead (name, logo, colour, footer line).
admin_suggest_email_design / admin_list_email_templates / admin_save_email_template / admin_rename_email_template / admin_delete_email_templateThree AI suggestions for an email's letterhead, each in a different look with its heading and button and one marked best fit, on the client's Claude key or NineTen's shared key; a client's saved letterhead templates.
admin_approve_campaign / admin_create_adhoc_campaign / admin_approve_adhoc_campaignActivate sequences and ad hoc blasts. Approvals are destructive — confirm.
Lifecycle
admin_campaign_wizardCampaign-planning wizard: one quick-pick menu at a time (goal → audience → sender → cadence → angles), options pre-filled from the client's real data. Read-only; start with step:'goal'.
admin_list_adhoc / admin_pause_adhoc / admin_resume_adhocList, pause, and resume ad hoc campaigns.
admin_cancel_adhoc / admin_delete_draftCancel (terminal) or delete a never-sent draft. Destructive — confirm.
admin_schedule_campaign / admin_set_start_date / admin_set_step_schedule / admin_toggle_schedule / admin_set_content_readySchedule a campaign, set/adjust a Manual campaign's start date (re-dates the cohort), set absolute per-step datetimes (one-off cohorts — overwrites waiting sends), pause/resume schedules, and gate content readiness.
admin_create_campaign / admin_update_campaign / admin_delete_draft_campaignScaffold, edit, or delete a sequence campaign (draft only for delete).
admin_add_step / admin_update_step / admin_delete_step / admin_reorder_stepsAdd, edit, delete, or reorder steps in any campaign.
admin_enroll_prospect / admin_bulk_enroll_prospects / admin_unenroll_prospectEnrol one prospect, enrol a picked cohort (explicit ids or a filter such as one upload batch, with a skipped-by-conflict summary), or cancel a single enrollment. All respect conflict_group.
Mailbox Connection (Aurinko)
admin_list_aurinko_apps / admin_register_aurinko_app / admin_update_aurinko_appManage the GLOBAL pool of Aurinko "servers" — each a BYOC Google OAuth client capped at 100 unverified users. Register a new server when the previous fills; each shows slots_used / available. Dashboard: the "Mailbox servers" page.
admin_rotate_aurinko_signing_secret / admin_reconcile_aurinko_slotsRotate a server's webhook Signing Secret (also update it in Aurinko — destructive, confirm) or recompute a server's slot counts from source of truth.
admin_list_client_mailboxes / admin_set_mailbox_enabledList a client's connected Gmail mailboxes (status, which server, no tokens) and kill-switch one (pause/resume webhook processing of its incoming replies).
admin_create_mailbox_invite / admin_list_mailbox_invites / admin_revoke_mailbox_inviteGenerate a shareable "connect your mailbox" link (app.nineten.ai/connect-mailbox?t=…) to send a client — they open it with no login and authorize their own Gmail. List / revoke existing links. Client modal: the "Client mailbox" section.
AI Training
admin_training_list_knowledge / admin_training_update_knowledge / admin_training_set_status / admin_training_bulk_set_status / admin_training_delete_knowledgeList, edit, and moderate a client's knowledge-base facts (draft → approved → archived) — only 'approved' facts feed the AI answer engine. Delete is destructive — confirm; prefer archiving.
admin_list_audiences / admin_suggest_audiences / admin_apply_audience_suggestions / admin_upsert_audience / admin_delete_audience / admin_set_knowledge_audiences / admin_suggest_knowledge_audiencesTarget audiences: the buyer segments a client's copy is written for. Suggest them from approved knowledge + the real prospect-category counts, review, then persist. Reports which categories no audience covers. Dashboard: the Training page's "Audiences" section.
admin_training_draft_from_url / admin_training_add_textBuild the knowledge base: draft a baseline from the client's website, or segment pasted document text into draft facts for review.
admin_training_start_session / admin_training_answer / admin_training_skip_question / admin_training_complete_session / admin_training_get_session / admin_training_list_sessionsRun an AI training interview — answers are distilled into draft facts; skip a question to move to the next topic; read a session's transcript or list past sessions.
admin_training_preview_answerPreview how the AI would answer a sample question using ONLY the client's approved knowledge + reply playbook. channel email (subject + body) or chat (short). Read-only — nothing is sent.
admin_training_start_test_chat / admin_training_test_reply / admin_training_delete_sessionRehearse a multi-turn AI reply as email or chat; email can be seeded with an existing campaign email. History recorded per session (rolling-summarized every ~10 messages) and deletable. Read-only — nothing is sent.
admin_training_demo_start / admin_training_demo_turn / admin_training_demo_deleteRun an end-to-end demo for a client: who we would target, how the AI answers them, how it lands a meeting. Simulated throughout — no prospecting credits spent, nothing sent, no calendar written.
admin_training_generate_samples / admin_training_list_samples / admin_training_apply_sample_feedbackPre-generate 5-10 sample role-play CONVERSATIONS (4-6 messages each, email/chat/mixed: the prospect opens, the AI replies via the live reply engine, a simulated prospect follows up, and every thread closes with the AI proposing a meeting) for client review — kind='sample', hidden from the Test-conversation list. Export to Word for client comment, then feed the feedback back (pass each sample's transcript): the AI proposes DRAFT knowledge facts + INACTIVE reply-overlay notes to approve. Dashboard: the Training page's "Sample role-play chats" section.
admin_training_get_review_guide / admin_training_apply_review_docApply a client's returned review pack: ticked facts approved, corrections applied, new notes drafted
admin_training_get_reply_skill / admin_training_update_reply_skill / admin_training_restore_reply_skillView + edit the GLOBAL reply-drafting playbook shared by all clients (versioned; restore an earlier version). Editing affects every client's drafting — destructive, confirm. Dashboard: the Playbooks page (Reply playbook section).
admin_training_list_reply_overlays / admin_training_add_reply_overlay / admin_training_toggle_reply_overlay / admin_training_delete_reply_overlayPer-client reply-playbook overlay notes layered on top of the global playbook (add / enable-disable / delete). Applies to that client's preview + test-reply immediately. Dashboard: the Training page's "Reply playbook overlay" section.
admin_training_draft_content_sequenceDraft a full N-email OUTBOUND campaign sequence (2-6 emails) for a stated intention, grounded in the client's approved knowledge + the outreach playbook. Read-only — save the ones you like as draft contents (admin_create_content) and attach to a campaign. Dashboard: the Training page's "Draft campaign content" section.
admin_training_get_content_skill / admin_training_update_content_skill / admin_training_restore_content_skill / admin_training_list/add/toggle/delete_content_overlayThe outreach content playbook behind draft_content_sequence: view + edit the GLOBAL playbook (versioned; restore; affects every client — confirm) and per-client overlay notes. Dashboard: the GLOBAL playbook is on the Playbooks page (Outreach playbook section); per-client overlay notes are on the Training page's "Outreach playbook overlay" section.
admin_training_generate_signoffAuto-build a client's email sign-off (Name / Title / Company / Contact / Website) from their sender identity + company profile + approved knowledge base; missing bits come back as bracketed [hints] to fill (never fabricated). Read-only. Complete the hints, then save via admin_training_add_content_overlay. Dashboard: the "Generate sign-off" button in the Training page's "Outreach playbook overlay" section.
admin_demoGuided per-company demo from chat: a three-item menu (draft content · prospecting · chat sample) you can return to at any time. Reads only; every revision is performed by the training tools an option points at. Run it against a demo profile seeded for the company being demoed.
admin_training_revise_content_draftRevise ONE email with the client's feedback, preserving the wording they did not ask to change. Returns the revision without saving it. Prefer this over re-running draft_content_sequence, which regenerates the whole sequence.
AI Replies
admin_list_ai_repliesCross-client queue of AI-drafted replies from the approval-first auto-reply engine (omit company_profile_id to see every client; filter by status draft/sent/dismissed/failed, channel, conversation_id, thread_id). Read-only. Dashboard: the "AI replies" page.
admin_approve_ai_reply / admin_dismiss_ai_replyApprove sends the AI's drafted reply on the client's own channel on their behalf (pass text/subject to edit first) — outward + irreversible, confirm-gated. Dismiss clears a draft without sending — one click. Both need the draft row's company_profile_id + draft_id.
admin_book_ai_appointmentCreate the real Cal.com appointment from the booking details the AI collected in the conversation (pass responses to correct an answer, start to move the time). The AI collects; a person books, unless the client's booking_link is on and the customer books on their own page. Outward + irreversible, confirm-gated. Does not send the reply. Dashboard: the booking panel inside a draft on the "AI replies" page.
admin_get_ai_reply_settings / admin_set_ai_reply_settingsRead or set a client's AI-reply per-channel enable flags and send mode (approval = a staffer reviews every draft; auto = routine replies send automatically while hot leads, missing-info answers, and possible opt-outs are held for review). Also on the company modal (mode) and the AI replies page (channels + mode). Set appointment_event_type_id to have the AI collect a prospect's booking details when they want to meet; a person books it unless booking_link is on (the customer then books on their own page from a link in the chat).
admin_get_shared_booking_link / admin_turn_on_shared_booking_link / admin_new_shared_booking_link / admin_turn_off_shared_booking_linkA client's shared booking link: one reusable address anyone can open to book the client's Cal.com meeting type, for staff or the client to share on WhatsApp, social media or a website. Read it, switch it on (needs Cal.com booking with a meeting type saved), replace it when it leaked, or switch it off. Replacing and switching off stop the old address for everyone who has it and are confirm-gated; bookings already made stay. Dashboard: AI replies, Channel settings.
admin_get_appointment_reminders / admin_set_appointment_reminders / admin_turn_on_appointment_reminders / admin_turn_off_appointment_remindersA client's WhatsApp appointment reminders: one WhatsApp from their own number 24 hours before each Cal.com booking that has a phone number, in English or Malay. Read them, change the language, the sending number or the staff test number, switch them on (confirm-gated: it sends real messages and Meta bills the client) or off. Dashboard: Companies, the company window, under API keys.
admin_list_calcom_event_types / admin_get_calcom_event_typeRead a client's Cal.com meeting types, and one type's booking questions (ask_fields = what a person must actually supply, so what the AI collects from a prospect). Use them to pick and preview the meeting type for appointment intake. The questions themselves are edited in the client's own Cal.com account.
admin_set_wp_credentials / admin_set_kie_keyConnect a client's WordPress site (its https:// address and application password, tested live against the site before saving, Rank Math detected automatically) and their kie.ai image key (tested against the free balance endpoint, so no image spend, and returns the credits left). A rejected credential is refused. The WordPress connect also refuses a plain http:// or private address and a site that redirects the test elsewhere; other problems save with a warning. Also on the company modal under API keys.
admin_set_heygen_key / admin_set_higgsfield_keyConnect a client's creative video accounts. HeyGen is tested live against its free quota endpoint before saving, so no video is generated and no quota is spent; Higgsfield publishes no validation endpoint, so it saves unverified and says so rather than implying a fault. Higgsfield takes a key id + key secret pair. Both also on the company modal under API keys. Generation itself is a later increment — these only store the credentials.
admin_set_freshsales_key / admin_disconnect_freshsalesConnect a client's Freshsales CRM, so the Freshsales connector (freshsale.nineten.ai) can hand their NineTen leads to their own salespeople. Takes the ACCOUNT ALIAS - for "https://acme.myfreshworks.com" that is "acme" - plus an API key; a pasted full URL is accepted and reduced. Tested live against Freshsales' read-only staff list before saving, so nothing is created, and it reports how many people can be assigned leads. That count is EVERYONE with a Freshsales login, not only salespeople - the endpoint has no role filter. Rejected and not saved only on a genuine 401 or 404, so a blip never overwrites a working key. Also on the company modal under API keys.
admin_set_dataforseo_key / admin_disconnect_dataforseo_keyConnect a company's DataForSEO account (keyword and search data for SEO): the API login and API password from app.dataforseo.com, API Access, which is not the sign-in password. Tested live against DataForSEO's free account endpoint before saving, so nothing is charged, and a verified save reports the balance. Rejected and not saved only when DataForSEO says the login or password is wrong; an IP whitelist or an unverified account saves with a warning. It pays for the search numbers on the client's SEO pages, only while their monthly budget is above 0 (the Search data row on the SEO page). Also on the company modal under API keys.
admin_set_snitcher_key / admin_disconnect_snitcher_keyConnect a company's Snitcher account (which companies visit their website): the API token from Snitcher, Settings, Account, API, not Snitcher's separate IP-to-Company key. Tested live against Snitcher's read-only workspace list before saving, so nothing is created or spent, and a verified save names the workspaces the token opens. Rejected and not saved only when Snitcher says the token is wrong (401); an outage or a rate limit saves with a warning. Visitor identification uses it to list this client's workspaces. Also on the company modal under API keys.
admin_generate_creative_image / admin_edit_creative_image / admin_get_creative_jobGenerate a social-post image from a description, on the CLIENT's own kie.ai credits (8 credits, about USD 0.04 each), or edit one of the client's generated images into a new version ("make the background light blue") by job_id or its media.zernio.com link while it is under 7 days old. Returns a ready-to-use media.zernio.com URL to pass to create_social_post — the image is re-hosted at generate time because kie's own link expires in about a day and would publish blank. Usually done inside the call (~22s); if it runs long you get a job_id to poll. Refused before any spend when the client has no kie.ai key, no Zernio key, too low a balance, or has hit the daily cap. Every finished image also comes back with a small preview the model can see.
admin_upload_seo_topics / admin_schedule_seo_batchUpload a client's topical-map xlsx as article topics, then space them across an editorial calendar from a start date and chosen weekdays. Both take dry_run:true - always preview first, and report the resolved column map and any per-row issues before writing. Dashboard: the "SEO content" page.
admin_list_seo_topics / admin_get_seo_topicThe article pipeline: every topic's status, scheduled date and WordPress link once drafted, plus the full generated body, meta and JSON-LD per topic. Drafted means it is waiting in the client's wp-admin for a person to publish it.
admin_publish_seo_topicPublish an article waiting for review - mode 'draft' creates the WordPress draft only, mode 'live' also makes it public at publish_at (default now). Refused unless the article is awaiting review.
admin_get_seo_settings / admin_set_seo_settingsPer-client SEO engine settings: the kill switch (enabled), article language, weekly publish cap, lanes, and the WordPress category and author to post under. Nothing is generated or published while enabled is false. set_seo_settings also holds the hero-image switches: images_enabled and image_style_prompt (draft one with admin_draft_seo_image_style). Hero images need both a style and a kie.ai key before they can turn on.
admin_reschedule_seo_topicChange when an approved article goes public, or publish it now. A future time is handed to WordPress, which holds the post and publishes it itself. Refused unless the article already has a WordPress post and is not public yet.
admin_draft_seo_image_stylePropose a house visual style for a client's blog hero images, drafted from their approved knowledge base. Read-only - returns a proposal and saves nothing. Save the edited text with admin_set_seo_settings image_style_prompt.
admin_generate_seo_image_nowQueue a hero image for one article already in WordPress - the manual backfill for a specific topic, since switching hero images on never back-fills old articles. Costs the client's kie.ai credits once the worker runs it, within about 15 minutes.
admin_get_focus_page / admin_set_focus_page / admin_switch_focus_page / admin_stop_focus_page / admin_extend_focus_pageGrow a page: one page a client picks, which the AI answers queue then plans supporting articles around. Every article approved for it links to it and is written first within the weekly cap. Set takes dry_run:true to read the page first; switch and stop are destructive - confirm. Dashboard: none; the client's portal has the page.
admin_connect_google / admin_disconnect_google / admin_get_seo_google_resultsGoogle Search Console: link a client to their Google site (the client first adds the NineTen robot's email in their Search Console as a Restricted user; the check answers with the email), stop the pull (destructive - confirm; the history is kept), and read what the daily pull stores: times shown, clicks, position and search terms per published article, the site's 13 weeks, and the site's own searches as Google counts them. Dashboard: the Google Search Console row on the SEO page.
admin_get_search_data_status / admin_refresh_keyword_demandSearch numbers from DataForSEO for a client's keywords: what this KL month has spent against the monthly budget (set with admin_set_seo_settings dfs_monthly_cap_usd; 0 is off, 1 switches a client on), who pays (the client's own DataForSEO login or NineTen's), what paused the fill, and how many keywords have numbers. Refresh fetches every keyword again on the next worker run, inside the budget. Dashboard: the Search data row on the SEO page.
admin_list_search_opportunities / admin_decide_search_opportunities / admin_start_opportunity_scanSearch opportunities from DataForSEO: the searches a client's website could win, as article ideas the client approves in their own portal (staff see the scores and can decide with them). Scan now looks again at once, about $0.20 to $0.30 a scan, charged to the client's monthly budget.
admin_start_site_audit / admin_get_site_audit"Check my site": crawl a client's site (from the site_url saved with admin_set_seo_settings) and grade it against ten rules - title/description length, missing descriptions, duplicate titles/descriptions, sitemap coverage, exactly one main heading per page, internal linking (the pages no other page links to), a noindex/none directive telling search engines to leave a page out, a canonical address that points off the client's own site, and whether robots.txt lets Google and Bing (Bing's row also covering Yahoo, DuckDuckGo and Copilot) read every page in the sitemap. The last six are graded only when they can be judged honestly: internal linking needs the crawl to have seen the whole site and every page's links, the heading rule is dropped when no page we read had exactly one heading (what a browser-rendered site looks like to a crawler that runs no JavaScript), the noindex/canonical rules are absent on any audit crawled before 2026-09-22 (the columns did not exist yet), and the Google and Bing rows are absent when robots.txt gave no readable answer, and on any audit started before 2026-09-23. So a capped audit, a robots-limited one, a site that builds its markup in the browser, or an older audit returns fewer rules, not a row of zeros - except noindex, which reports even when every page fails it, since a directive on the page is not our own blindness (the WordPress "discourage search engines" switch, flipped everywhere, is the one finding this worth most). A page the site hides from search is left out of the duplicate-wording and internal-linking rules, and WooCommerce's cart/checkout/my-account pages are left out of the noindex rule - Woo writes that directive itself, so reporting it is reporting the shop for working. Left out means out of the denominator too, never counted as a pass. Refuses with a clear reason if there is no usable website address on file, or a check is already queued/running. Takes a few minutes; poll get_site_audit for the result.