Scripts for managing a Notifyer account via the Console API
( https://api.insightssystem.com). All Console API requests authenticate with
Authorization: Bearer <token>.
bash
cd skills/setup-notifyer
npm install # no dependencies required yet (uses built-in fetch)
Set environment variables:
bash
export NOTIFYER_API_BASE_URL="https://api.insightssystem.com"
export NOTIFYER_API_TOKEN="<jwt-token>" # from login.js
bash
node scripts/create-account.js \
--name "Jane Smith" \
--email jane@company.com \
--password "Secure@123" \
--phone 14155550123
--reason is optional (shown as "(optional)" in the signup UI). Supply it to help the support team understand the use case.
Returns { ok: true, data: { authToken, user, apiKey } } on success.
The authToken can be used immediately as NOTIFYER_API_TOKEN.
bash
node scripts/login.js \
--email jane@company.com \
--password "Secure@123"
Returns { ok: true, data: { authToken } }.
bash
export NOTIFYER_API_TOKEN="<authToken from above>"
bash
node scripts/get-me.js
Returns { ok: true, data: { id, name, email, role, phone_number, ... } }.
bash
node scripts/doctor.js
node scripts/doctor.js --pretty # human-readable pass/fail report to stderr
Validates all four prerequisites in one command:
NOTIFYER_API_BASE_URL — set and starts with https://NOTIFYER_API_TOKEN) — valid and accepted by /auth/meisConnected: true (and detects degraded Meta states)active, trialing, or new_userReturns { ok: true, data: { all_healthy: true, checks: { base_url, token, connection, plan } } }.
Returns { ok: false, ... } (exit 1) if any check fails, with a fix hint for each failure.
Run doctor.js before any other script when troubleshooting unexpected failures.
bash
node scripts/get-connection-status.js
node scripts/get-connection-status.js --pretty # human-readable summary to stderr
Returns { ok: true, data: { isConnected, degraded, meta_errors, has_embedded_user, registration, subscription, payment_method_added, is_template_has, is_message_tested, is_profile_picture_added, onboarding_steps_completed } }.
isConnected = true means the phone number has both successful Meta registration and
subscription — it is ready to send messages.
degraded = true means isConnected is true but Meta returned hidden errors inside
the whatsapp_response payload (e.g. two-step PIN mismatch, account restricted). Always
check degraded alongside isConnected — a degraded connection may fail silently.
meta_errors contains the extracted error details as a string array.
Use this when get-connection-status.js shows a failed or stale registration/subscription,
or after connecting a new number in the console.
bash
node scripts/refresh-connection.js
node scripts/refresh-connection.js --pretty
Returns the same shape as get-connection-status.js.
Daily limit warning: Meta limits how many times per day re-registration can be attempted. If the response indicates a limit error, wait 24 hours before retrying.
bash
node scripts/list-plans.js # all plans
node scripts/list-plans.js --billing monthly # monthly only
node scripts/list-plans.js --billing annual # annual only
node scripts/list-plans.js --tier pro # Pro tier only
node scripts/list-plans.js --tier basic --billing monthly
node scripts/list-plans.js --pretty # human-readable table to stderr
Returns all plan tiers grouped by { monthly: { basic, pro, agency }, annual: { ... } }.
Each tier entry contains id, price (in dollars), unique_numbers (contact limit),
stripe_price_id, and What_it_includes.
Plans: basic = Bulk Message (no integrations/bots), pro = full features,
agency = Pro + multiple phone numbers.
bash
node scripts/get-user-plan.js
node scripts/get-user-plan.js --pretty
Returns { usages, latest_plan: { status, plan_amount, unique_number_limit, total_unique_number_count, end_time, ... } }.
plan_amount is in cents — the script adds a plan_amount_dollars convenience field.
bash
node scripts/list-members.js # all members
node scripts/list-members.js --page 1 --per-page 25 # paginate
node scripts/list-members.js --labels # also show available label names
node scripts/list-members.js --pretty # human-readable table to stderr
Returns { items: TeamMember[], team_seat: { included_seats } }.
Members are sorted by role (Super Admin → Admin → Team Member (All Labels) → Team Member).
bash
node scripts/invite-member.js \
--name "Jane Smith" \
--email jane@company.com \
--password "Secure@2024" \
--role "Team Member" \
--labels "Sales,Support"
Creates a full account immediately (no email invite flow). Share credentials out-of-band.
Assignable roles: Admin, Team Member (All Labels), Team Member.
Labels (comma-separated) are only used for Team Member role — Admin roles get all labels automatically.
bash
# Promote to Admin
node scripts/update-member.js --id <id> --role Admin
# Assign new labels (replaces current list)
node scripts/update-member.js --id <id> --labels "Sales,VIP"
# Clear all labels
node scripts/update-member.js --id <id> --labels ""
# Rename + reset password
node scripts/update-member.js --id <id> --name "John Doe" --password "NewPass@99"
There is no separate change-role endpoint — role, labels, name and password are all
updated through the same PATCH /api:-4GSCDHb/auth/user call. The script auto-fetches
current values and only changes what you supply.
bash
node scripts/remove-member.js --id <id> --confirm
Permanent and immediate. --confirm is required to prevent accidental deletion.
Super Admin (account owner) cannot be removed.
bash
node scripts/list-labels.js
node scripts/list-labels.js --pretty # human-readable table to stderr
Returns { labels: Label[], count: n }.
Each label has id, label (display name), keywords (auto-assignment triggers),
user_id, and created_at.
Super Admin and Admin see all workspace labels. Team Members see only the labels assigned to their account.
bash
node scripts/create-label.js --label "Sales"
node scripts/create-label.js --label "Support" --keywords "help,issue,ticket"
Label names must be unique. keywords are comma-separated trigger words that
auto-assign the label when a contact message contains a match.
bash
# Add keywords
node scripts/update-label-keywords.js --id 5 --add "urgent,priority"
# Remove a keyword
node scripts/update-label-keywords.js --id 5 --remove "old-keyword"
# Replace the entire keyword list
node scripts/update-label-keywords.js --id 5 --set "buy,purchase,order"
# Clear all keywords
node scripts/update-label-keywords.js --id 5 --set ""
# Rename a label
node scripts/update-label-keywords.js --id 5 --label "VIP Customers"
--add, --remove, and --set are mutually exclusive. The script fetches the
current label first so unchanged fields are preserved.
bash
node scripts/delete-label.js --id 5 --confirm
Permanent and immediate. --confirm is required to prevent accidental deletion.
After deletion, manually remove the label from any team members that had it
assigned using update-member.js --labels.
bash
node scripts/get-api-key.js
node scripts/get-api-key.js --pretty # prints key to stderr for easy copying
Returns { id, api_key, user_id, created_at }.
The api_key value is the credential used by Make, Zapier, n8n, and custom scripts
to send messages via the developer API. It authenticates as a raw Authorization
header (no Bearer prefix) — different from NOTIFYER_API_TOKEN.
Bearer <jwt>), Chat ( <jwt> raw), Developer
( <api_key> raw). The console JWT and the Developer API key are different credentials.
get-api-key.js uses console auth to retrieve the key; the key itself is then used
by external tools as a raw Authorization header.get-user-plan.js before directing a user to set up integrations.api_key
as a long-lived secret; store it in env vars, never in source control.send_template_message_by_api uses the API key, not the JWT — when calling
POST /api:hFrjh8a1/send_template_message_by_api, set
Authorization: <api_key> (no Bearer). phone_number is passed as text here
(unlike console APIs where it is an integer).sub_channel: "onboarding_test" is a special mode that updates embedded_users
and is only for test sends. Omit sub_channel (or pass "") for production sends.list-labels.js, create-label.js,
update-label-keywords.js, and delete-label.js all use
Authorization: <token> (no Bearer prefix). The same NOTIFYER_API_TOKEN
from login.js works — notifyer-api.js handles the format difference via
AUTH_MODE_CHAT.create-label.js returns
{ ok: false, blocked: true } if a label with the same name already exists.keywords is a full replacement — update-label-keywords.js --set replaces
the entire list. Use --add / --remove to make incremental changes.update-label-keywords.js and
delete-label.js both call GET /web/label_management to look up the target by
id before mutating.{ deleted: true, id, label } from the pre-flight fetch.delete-label.js,
update affected team members manually with update-member.js --labels.phone_number must be a number — send as integer (e.g. 14155550123),
not a string. Xano types this field as integer.@!#$%^&*).Origin header is injected automatically. notifyer-api.js adds
Origin: https://console.notifyer-systems.com for console-mode requests and
Origin: https://chat.notifyer-systems.com for chat-mode requests. You never need
to pass it manually. If a script sets Origin via extraHeaders, that value
takes precedence. This fixes a class of silent 401s that occurred when the header
was missing on Xano endpoints that validate it.authToken in NOTIFYER_API_TOKEN. Never commit
tokens to source control.{ ok: false, error: "..." }.invite-member.js creates the account directly.
Share credentials with the new member out-of-band. There is no "pending invite" state.update-member.js fetches current state first — you only need to supply the fields
you want to change; unchanged fields are read from the existing member and re-sent.labels replaces, not appends — update-member.js --labels "Sales" sets labels
to exactly ["Sales"], removing any previous ones.update-member.js sends labels: []
automatically when the effective role is not Team Member.plan_amount is in cents — latest_plan.plan_amount is in cents (Stripe convention).
get-user-plan.js adds a plan_amount_dollars field for convenience.POST /api:Mk_r6mq0/sessions creates a Stripe
checkout session that requires a browser redirect. Agents cannot subscribe on behalf
of a user — direct them to https://console.notifyer-systems.com/pricing-plans.status ∈ ["active","trialing"] and usages < unique_number_limit.get-connection-status.js returns the status of that single number.isConnected vs has_embedded_user — has_embedded_user means a Meta
Facebook account has been linked. isConnected ( registration.success && subscription.success) means WhatsApp messaging is actually ready. Always
check isConnected before sending messages.refresh-connection.js re-triggers Meta
registration. Meta rate-limits this per day. If you see a daily limit error,
wait 24 hours.Notifyer's backend uses Xano-style API group IDs in the URL path:
GroupPrefixUsed forAuth/api:-4GSCDHbSignup, login, get-me, api_key, team member CRUDMessage Sending/api:hFrjh8a1Send template messages via Developer API keyWhatsApp Connection/api:P5grzx1uConnection status, Meta re-registrationWeb/Console/api:bVXsw_FDLabel CRUD ( /web/label_management), recipients, teamRoles/api:eWoClqoZGet available label names for member assignmentPlans/api:JZAUyiCsPlan listing and selection
FileDescriptionscripts/lib/notifyer-api.jsBase HTTP client — loads config, sends requests, handles errorsscripts/lib/args.jsCLI argument parser (flags, booleans, numbers)scripts/lib/result.jsStandard output helpers — ok(), err(), printJson()``scripts/create-account.js``POST /api:-4GSCDHb/auth/signup — create a new Notifyer accountscripts/login.js``POST /api:-4GSCDHb/auth/login — login and get an auth tokenscripts/get-me.js``GET /api:-4GSCDHb/auth/me — get the authenticated user's profilescripts/get-connection-status.js``GET /api:P5grzx1u/is_user_embedded — WhatsApp connection statusscripts/refresh-connection.js``POST /api:P5grzx1u/refresher_of_registration_subscription — force re-sync with Metascripts/list-plans.js``GET /api:JZAUyiCs/plans?filter=… — list available subscription plan tiersscripts/get-user-plan.js``GET /api:JZAUyiCs/user_plan — current subscription and usagescripts/list-members.js``GET /api:-4GSCDHb/auth/get_team_member — list team members; --labels also fetches available label namesscripts/invite-member.js``POST /api:-4GSCDHb/auth/create_team_member — create a team member accountscripts/update-member.js``PATCH /api:-4GSCDHb/auth/user — update role, labels, name, or passwordscripts/remove-member.js``DELETE /api:-4GSCDHb/auth/delete_team_member/:id — permanently remove a memberscripts/list-labels.js``GET /api:bVXsw_FD/web/label_management — list workspace labels (role-filtered)scripts/create-label.js``POST /api:bVXsw_FD/web/label_management — create a new labelscripts/update-label-keywords.js``PATCH /api:bVXsw_FD/web/label_management/:id — update name or keywords (fetch-then-patch)scripts/delete-label.js``DELETE /api:bVXsw_FD/web/label_management/:id — permanently delete a labelscripts/get-api-key.js``GET /api:-4GSCDHb/api_key — retrieve the Developer API key for Make/Zapier/n8nscripts/doctor.jsPre-flight health check — validates base URL, token, WhatsApp connection, and plan status in one command
references/account-reference.md — Full API reference for auth endpoints, field types, error codes, and token usagereferences/whatsapp-connection-reference.md — Connection status fields, onboarding checklist, rate limits, and architecture notesreferences/plans-reference.md — Plan filters, PricingTier shape, LatestPlan fields, status values, billing modelreferences/team-reference.md — Role system, team member CRUD endpoints, label assignment rules, common workflowsreferences/labels-reference.md — Label data model, all CRUD endpoints, keyword auto-assignment behaviour, role-filtering rulesreferences/api-key-reference.md — Developer API key retrieval, all three auth modes, and send_template_message_by_api reference for Make/Zapier/n8nassets/signup-example.json — Example signup request payloadassets/connection-status-example.json — Example connection status responseassets/user-plan-example.json — Example response from get-user-plan.jsNOTIFYER_API_BASE_URL must be https://. All three skills enforce this at startup — any http:// or non-HTTPS URL is rejected immediately to prevent tokens being sent unencrypted or to a rogue host.--password is visible in the OS process list. CLI flags are readable via ps aux or /proc/<pid>/cmdline for the lifetime of the process. On shared or monitored machines, prefer injecting credentials via environment variables or a secrets manager rather than bare CLI flags.login.js is printed to stdout. This is by design — the agent must capture it to export NOTIFYER_API_TOKEN. In orchestrated environments, ensure stdout is not persisted to unprotected logs. Treat the token like a session cookie.get-api-key.js is printed to both stdout and stderr. Store it immediately in a secrets manager. It provides direct WhatsApp send access without a session login.get-connection-status.js and refresh-connection.js can manage the connection programmatically.PATCH /api:0hqyGRIz/whatsapp_verification/{userId} endpoint (OTP submission during phone re-authentication) is triggered by the console UI. There is no script for this flow.create-account.js creates a full Notifyer workspace. There is no delete-account endpoint.GET /reset_password?email= to trigger email + PATCH /reset_password to set the new password) requires the user to click a link in the email. There is no agent-accessible reset path that bypasses the email step.refresh-connection.js re-syncs an existing connection. It cannot re-initiate a fully disconnected or revoked WABA — that requires going through the browser-based embedded signup again.list-plans.js and get-user-plan.js are read-only. Changing plans ( POST /api:Mk_r6mq0/sessions), accessing the billing portal ( POST /api:Mk_r6mq0/portal), and buying credits ( POST /api:Mk_r6mq0/add_credits) are Stripe redirect flows — not scriptable.PATCH /profile_picture_update, PATCH /payment_method_update, and PATCH /test_message_update are completion flags set by the console onboarding UI. There are no scripts for these — they do not affect core messaging functionality once the account is set up.update-member.js. Super Admin is set by Notifyer at workspace creation.text
[setup-notifyer file map]|root: .
|.:{package.json,SKILL.md}
|assets:{connection-status-example.json,signup-example.json,user-plan-example.json}
|references:{account-reference.md,api-key-reference.md,labels-reference.md,plans-reference.md,team-reference.md,whatsapp-connection-reference.md}
|scripts:{create-account.js,create-label.js,delete-label.js,doctor.js,get-api-key.js,get-connection-status.js,get-me.js,get-user-plan.js,invite-member.js,list-labels.js,list-members.js,list-plans.js,login.js,refresh-connection.js,remove-member.js,update-label-keywords.js,update-member.js}
|scripts/lib:{args.js,notifyer-api.js,result.js}