Developer Reference

API Reference

Full reference for the Fixer Nation REST API — built for both internal admin use and external integrations. Base URL: https://fixernation.org

Auth:NextAuth session cookie
Format:JSON
Versioning:None (latest)

Overview

The Fixer Nation REST API follows standard HTTP conventions. Every request and response uses JSON unless stated otherwise. The base URL for all endpoints is https://fixernation.org. The API is designed primarily for browser-based admin use; external integrations authenticate via a NextAuth session cookie obtained by signing in.

Authentication

Session-based auth via NextAuth.js. After signing in, the browser session token is stored in a cookie and included automatically. For programmatic access, perform a sign-in request, capture the session cookie, and pass it with each subsequent request. Over HTTPS the cookie is named __Secure-next-auth.session-token. Over HTTP (dev only) it is next-auth.session-token.

POST/api/auth/registerPublic

Create a new user account

Request Body

NameTypeRequiredDescription
emailstringYesEmail address for the account
passwordstringYesPassword (min 8 characters)
namestringNoDisplay name
Response
{"message":"Verification email sent. Please check your inbox."}
curl
curl -X POST https://fixernation.org/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email":"jane@example.com","password":"secret123","name":"Jane"}'
POST/api/auth/forgot-passwordPublic

Request a password reset link

Request Body

NameTypeRequiredDescription
emailstringYesRegistered email address
Response
{"message":"If that email is registered, a reset link is on its way."}
curl
curl -X POST https://fixernation.org/api/auth/forgot-password \
  -H "Content-Type: application/json" \
  -d '{"email":"jane@example.com"}'

Contacts

Contacts are the core CRM entity. A contact can exist independently of a user account, enabling you to manage newsletter subscribers, imported lists, and event attendees who have never signed up to the platform.

GET/api/admin/contactsAdmin

List contacts

Query Parameters

NameTypeRequiredDescription
qstringNoFull-text search across email, name, phone, company
tagstringNoFilter by tag value
attributionstringNoFilter by attribution source: ORGANIC, REFERRAL, IMPORT, MANUAL, INVITE, SUBSCRIBE_FORM, CAMPAIGN
topicstringNoFilter by newsletter topic slug
liststringNoFilter by contact list ID
pagenumberNoPage number (default 1)
limitnumberNoResults per page (default 50, max 200)
Response
{
  "contacts": [
    {
      "id": "clx1abc...",
      "email": "jane@example.com",
      "firstName": "Jane",
      "lastName": "Smith",
      "phone": null,
      "company": null,
      "source": "import",
      "createdAt": "2026-08-15T12:00:00.000Z",
      "userId": null,
      "attribution": { "source": "IMPORT" },
      "tags": [{"tag": "newsletter"}, {"tag": "vip"}]
    }
  ],
  "total": 1,
  "page": 1,
  "pages": 1
}
curl
curl "https://fixernation.org/api/admin/contacts?q=jane&tag=newsletter" \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/contactsAdmin

Create a contact

Request Body

NameTypeRequiredDescription
emailstringYesContact email address
firstNamestringNoFirst name
lastNamestringNoLast name
phonestringNoPhone number
companystringNoCompany or organization
sourcestringNoContact origin (admin, import, form, etc.)
tagsstring[]NoTags to apply on creation
Response
{
  "id": "clx1abc...",
  "email": "jane@example.com",
  "firstName": "Jane",
  "createdAt": "2026-08-16T09:00:00.000Z"
}
curl
curl -X POST https://fixernation.org/api/admin/contacts \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"email":"jane@example.com","firstName":"Jane","tags":["newsletter"]}'
GET/api/admin/contacts/:idAdmin

Get a contact

Response
{
  "id": "clx1abc...",
  "email": "jane@example.com",
  "firstName": "Jane",
  "lastName": "Smith",
  "attribution": {
    "source": "ORGANIC",
    "attributedAt": "2026-08-15T12:00:00.000Z",
    "campaignId": null
  },
  "tags": [{"id":"t1","tag":"newsletter"}],
  "notes": [],
  "addresses": [],
  "identities": [],
  "subscriptions": [],
  "customFields": []
}
curl
curl https://fixernation.org/api/admin/contacts/clx1abc \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
PUT/api/admin/contacts/:idAdmin

Update contact fields

Request Body

NameTypeRequiredDescription
firstNamestringNoUpdated first name
lastNamestringNoUpdated last name
phonestringNoUpdated phone
companystringNoUpdated company
emailstringNoUpdated email (must be unique)
curl
curl -X PUT https://fixernation.org/api/admin/contacts/clx1abc \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"firstName":"Jane","company":"Acme Corp"}'
DELETE/api/admin/contacts/:idAdmin

Delete a contact

Note: Permanently deletes the contact and all associated records (tags, notes, subscriptions, attribution). Cannot be undone.
curl
curl -X DELETE https://fixernation.org/api/admin/contacts/clx1abc \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
PATCH/api/admin/contacts/:idAdmin

Sub-actions: add/remove tags, notes, attribution, consent

A single PATCH endpoint that dispatches different actions based on the action field in the request body.

Request Body

NameTypeRequiredDescription
actionstringYesadd-note | add-tag | remove-tag | set-attribution | set-consent
notestringNoNote body (add-note)
tagstringNoTag string (add-tag, remove-tag)
sourcestringNoAttribution source enum (set-attribution)
campaignIdstringNoCampaign ID for CAMPAIGN attribution
topicstringNoNewsletter topic slug (set-consent)
optedInbooleanNoConsent value (set-consent)
curl
# Add a tag
curl -X PATCH https://fixernation.org/api/admin/contacts/clx1abc \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"action":"add-tag","tag":"vip"}'

# Set attribution
curl -X PATCH https://fixernation.org/api/admin/contacts/clx1abc \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"action":"set-attribution","source":"REFERRAL"}'
GET/api/admin/contacts/:id/activityAdmin

Get the contact activity timeline

Response
{
  "events": [
    {
      "id": "ev1",
      "type": "SUBSCRIPTION_UPDATED",
      "description": "Subscribed to Morning Boost",
      "occurredAt": "2026-08-15T12:05:00.000Z"
    }
  ]
}
curl
curl https://fixernation.org/api/admin/contacts/clx1abc/activity \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/contacts/:id/mergeAdmin

Merge a duplicate into this contact

Merges the source contact (sourceId) into this one (URL :id). Tags, notes, and subscriptions are transferred. The source contact is deleted.

Request Body

NameTypeRequiredDescription
sourceIdstringYesID of the duplicate contact to merge from and delete
curl
curl -X POST https://fixernation.org/api/admin/contacts/clx1abc/merge \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"sourceId":"clxDUPLICATE"}'
GET/api/admin/contacts/exportAdmin

Export contacts as CSV

Returns a CSV file download. Accepts the same filters as the list endpoint.

Query Parameters

NameTypeRequiredDescription
qstringNoSearch query
tagstringNoFilter by tag
liststringNoFilter by list ID
curl
curl "https://fixernation.org/api/admin/contacts/export?tag=newsletter" \
  -H "Cookie: __Secure-next-auth.session-token=<token>" -o contacts.csv
POST/api/admin/contacts/importAdmin

Import contacts from CSV

Accepts a multipart/form-data upload. CSV must have at minimum an email column.

Request Body

NameTypeRequiredDescription
fileFileYesCSV file (multipart/form-data)
listIdstringNoAdd all imported contacts to this list
tagstringNoTag to apply to all imported contacts
Response
{"created": 148, "skipped": 3, "errors": []}
curl
curl -X POST https://fixernation.org/api/admin/contacts/import \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -F "file=@contacts.csv" \
  -F "tag=import-aug-2026"

Contact Addresses

GET/api/admin/contacts/:id/addressesAdmin

List addresses for a contact

curl
curl https://fixernation.org/api/admin/contacts/clx1abc/addresses \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/contacts/:id/addressesAdmin

Add an address

Request Body

NameTypeRequiredDescription
streetstringNoStreet line 1
street2stringNoUnit, suite, etc.
citystringNoCity
statestringNoState abbreviation
zipstringNoZIP or postal code
countrystringNoCountry code (default US)
labelstringNohome, work, billing, etc.
curl
curl -X POST https://fixernation.org/api/admin/contacts/clx1abc/addresses \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"street":"123 Main St","city":"Austin","state":"TX","zip":"78701"}'
PUT/api/admin/contacts/:id/addresses/:addrIdAdmin

Update or delete an address

Note: Send DELETE to remove the address.
curl
curl -X PUT https://fixernation.org/api/admin/contacts/clx1abc/addresses/addr1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"city":"Houston","zip":"77001"}'

Contact Identities

A contact can have multiple email addresses, phone numbers, or external IDs. The primary email is on the Contact record; identities store additional linked identifiers.

GET/api/admin/contacts/:id/identitiesAdmin

List identities

curl
curl https://fixernation.org/api/admin/contacts/clx1abc/identities \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/contacts/:id/identitiesAdmin

Add an identity

Request Body

NameTypeRequiredDescription
typestringYesemail, phone, or external
valuestringYesThe identity value
labelstringNowork, personal, etc.
curl
curl -X POST https://fixernation.org/api/admin/contacts/clx1abc/identities \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"type":"email","value":"jane.work@acme.com","label":"work"}'
DELETE/api/admin/contacts/:id/identities/:identityIdAdmin

Remove an identity

curl
curl -X DELETE https://fixernation.org/api/admin/contacts/clx1abc/identities/ident1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>"

Custom Field Values

Set values for admin-defined custom fields on a contact. Field definitions are managed via /api/admin/custom-fields.

PUT/api/admin/contacts/:id/custom-fieldsAdmin

Set custom field values for a contact

Request Body

NameTypeRequiredDescription
fieldsobject[]YesArray of {definitionId, value} pairs
curl
curl -X PUT https://fixernation.org/api/admin/contacts/clx1abc/custom-fields \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"fields":[{"definitionId":"def1","value":"Gold"}]}'

Contact Lists

Named collections of contacts used as campaign audiences. Contacts can appear on multiple lists.

GET/api/admin/listsAdmin

List all contact lists

Response
{
  "lists": [
    {
      "id": "lst1",
      "name": "Newsletter Subscribers",
      "description": null,
      "createdAt": "2026-08-01T00:00:00.000Z",
      "_count": { "members": 482 }
    }
  ]
}
curl
curl https://fixernation.org/api/admin/lists \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/listsAdmin

Create a list

Request Body

NameTypeRequiredDescription
namestringYesList name (must be unique)
descriptionstringNoOptional description
curl
curl -X POST https://fixernation.org/api/admin/lists \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Newsletter Subscribers"}'
GET/api/admin/lists/:idAdmin

Get a list with member count

curl
curl https://fixernation.org/api/admin/lists/lst1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
PUT/api/admin/lists/:idAdmin

Update list name or description

curl
curl -X PUT https://fixernation.org/api/admin/lists/lst1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Monthly Newsletter"}'
PATCH/api/admin/lists/:idAdmin

Add or remove contacts from a list

Request Body

NameTypeRequiredDescription
actionstringYesadd-contacts or remove-contacts
contactIdsstring[]YesArray of contact IDs
curl
curl -X PATCH https://fixernation.org/api/admin/lists/lst1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"action":"add-contacts","contactIds":["clx1abc","clx2def"]}'
DELETE/api/admin/lists/:idAdmin

Delete a list

Note: Deleting a list does not delete the contacts on it.
curl
curl -X DELETE https://fixernation.org/api/admin/lists/lst1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>"

Campaigns

Email campaigns targeting a contact list. Support A/B variants, scheduled sends, and detailed delivery analytics.

GET/api/admin/campaignsAdmin

List campaigns

Query Parameters

NameTypeRequiredDescription
statusstringNoDRAFT | SCHEDULED | SENDING | SENT | PAUSED | CANCELLED
qstringNoSearch by name
Response
{
  "campaigns": [
    {
      "id": "cmp1",
      "name": "August Newsletter",
      "status": "DRAFT",
      "subject": "Welcome to August",
      "listId": "lst1",
      "scheduledAt": null,
      "sentAt": null,
      "createdAt": "2026-08-15T12:00:00.000Z",
      "_count": { "sends": 0 }
    }
  ]
}
curl
curl "https://fixernation.org/api/admin/campaigns?status=DRAFT" \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/campaignsAdmin

Create a campaign

Request Body

NameTypeRequiredDescription
namestringYesInternal campaign name
subjectstringYesEmail subject line
fromNamestringYesSender display name
fromEmailstringYesSender email address
htmlBodystringNoEmail HTML content (or use templateId)
textBodystringNoPlain-text fallback
templateIdstringNoBase it on an email template
listIdstringNoTarget contact list ID
scheduledAtstringNoISO 8601 date — schedule for future delivery
curl
curl -X POST https://fixernation.org/api/admin/campaigns \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"August Newsletter","subject":"Welcome to August","fromName":"Fixer Nation","fromEmail":"campaigns@fixernation.org","listId":"lst1","htmlBody":"<h1>Hello!</h1>"}'
GET/api/admin/campaigns/:idAdmin

Get a campaign with variants and metrics

curl
curl https://fixernation.org/api/admin/campaigns/cmp1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
PUT/api/admin/campaigns/:idAdmin

Update a DRAFT campaign

Note: Only DRAFT campaigns can be modified. Sent campaigns are read-only.
curl
curl -X PUT https://fixernation.org/api/admin/campaigns/cmp1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"subject":"Updated Subject Line"}'
POST/api/admin/campaigns/:idAdmin

Trigger send or recompute delivery metrics

Note: The send action transitions the campaign from DRAFT to SENDING and begins delivery. Scheduled campaigns queue for the scheduledAt time.

Request Body

NameTypeRequiredDescription
actionstringYessend or compute_metrics
curl
# Send immediately
curl -X POST https://fixernation.org/api/admin/campaigns/cmp1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"action":"send"}'

# Refresh delivery stats
curl -X POST https://fixernation.org/api/admin/campaigns/cmp1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"action":"compute_metrics"}'
DELETE/api/admin/campaigns/:idAdmin

Delete a campaign

Note: Only DRAFT and CANCELLED campaigns can be deleted.
curl
curl -X DELETE https://fixernation.org/api/admin/campaigns/cmp1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/campaigns/:id/variantsAdmin

Add an A/B variant to a campaign

Request Body

NameTypeRequiredDescription
labelstringYesVariant label (A, B, etc.)
subjectstringYesVariant subject line
htmlBodystringNoVariant HTML content
splitPercentnumberNoAudience percentage for this variant (0–100)
curl
curl -X POST https://fixernation.org/api/admin/campaigns/cmp1/variants \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"label":"B","subject":"Try This Subject","splitPercent":50}'
POST/api/admin/campaigns/preview-audienceAdmin

Preview estimated audience size

Request Body

NameTypeRequiredDescription
listIdstringNoTarget list ID
excludeUnsubscribedbooleanNoExclude suppressed contacts (default true)
Response
{"count": 847, "suppressed": 12, "deliverable": 835}
curl
curl -X POST https://fixernation.org/api/admin/campaigns/preview-audience \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"listId":"lst1","excludeUnsubscribed":true}'
POST/api/admin/campaigns/test-sendAdmin

Send a test email to a specific address

Request Body

NameTypeRequiredDescription
campaignIdstringYesCampaign to preview
tostringYesRecipient email address
curl
curl -X POST https://fixernation.org/api/admin/campaigns/test-send \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"campaignId":"cmp1","to":"admin@fixernation.org"}'

Email Templates

Reusable email templates with {{variable}} substitution. Use as a starting point when creating campaigns.

GET/api/admin/email-templatesAdmin

List email templates

curl
curl https://fixernation.org/api/admin/email-templates \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/email-templatesAdmin

Create a template

Request Body

NameTypeRequiredDescription
namestringYesTemplate name
subjectstringYesDefault subject (may contain {{variables}})
htmlBodystringYesHTML template body
textBodystringNoPlain-text fallback
categorystringNoOrganizational category
curl
curl -X POST https://fixernation.org/api/admin/email-templates \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Welcome","subject":"Welcome, {{first_name}}!","htmlBody":"<h1>Hi {{first_name}}</h1>"}'
PUT/api/admin/email-templates/:idAdmin

Update a template

curl
curl -X PUT https://fixernation.org/api/admin/email-templates/tpl1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"subject":"Updated Subject"}'
DELETE/api/admin/email-templates/:idAdmin

Delete a template

curl
curl -X DELETE https://fixernation.org/api/admin/email-templates/tpl1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>"

Automations

Multi-step journey automations triggered by platform events (signup, role change, tag added, event RSVP). Steps can send emails, wait, add/remove tags, or evaluate conditions.

GET/api/admin/automationsAdmin

List automation journeys

curl
curl https://fixernation.org/api/admin/automations \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/automationsAdmin

Create a journey

Request Body

NameTypeRequiredDescription
namestringYesJourney name
triggerstringYesSIGNUP | ROLE_CHANGE | TAG_ADDED | EVENT_RSVP | MANUAL
triggerConfigobjectNoTrigger-specific config (e.g. {tag:'vip'} for TAG_ADDED)
activebooleanNoWhether the journey is active (default false)
curl
curl -X POST https://fixernation.org/api/admin/automations \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Welcome Series","trigger":"SIGNUP","active":true}'
GET/api/admin/automations/:idAdmin

Get a journey with all steps

curl
curl https://fixernation.org/api/admin/automations/jrn1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
PUT/api/admin/automations/:idAdmin

Update journey settings

curl
curl -X PUT https://fixernation.org/api/admin/automations/jrn1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"active":false}'
PATCH/api/admin/automations/stepAdmin

Update a step's config or canvas position

Request Body

NameTypeRequiredDescription
stepIdstringYesStep ID to update
configobjectNoStep config (templateId, waitDuration, tag, etc.)
posXnumberNoCanvas X position
posYnumberNoCanvas Y position
curl
curl -X PATCH https://fixernation.org/api/admin/automations/step \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"stepId":"step1","config":{"templateId":"tpl1","waitDuration":86400}}'
PUT/api/admin/automations/reorder-stepsAdmin

Reorder steps in a journey

Request Body

NameTypeRequiredDescription
journeyIdstringYesJourney ID
stepIdsstring[]YesOrdered step IDs
curl
curl -X PUT https://fixernation.org/api/admin/automations/reorder-steps \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"journeyId":"jrn1","stepIds":["step2","step1","step3"]}'
POST/api/admin/automations/enrollAdmin

Manually enroll a contact in a journey

Request Body

NameTypeRequiredDescription
journeyIdstringYesJourney to enroll in
contactIdstringYesContact to enroll
curl
curl -X POST https://fixernation.org/api/admin/automations/enroll \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"journeyId":"jrn1","contactId":"clx1abc"}'
GET/api/admin/automations/enrollmentsAdmin

List journey enrollments

Query Parameters

NameTypeRequiredDescription
journeyIdstringNoFilter by journey
contactIdstringNoFilter by contact
statusstringNoACTIVE | COMPLETED | PAUSED | CANCELLED | FAILED
curl
curl "https://fixernation.org/api/admin/automations/enrollments?status=ACTIVE" \
  -H "Cookie: __Secure-next-auth.session-token=<token>"

Newsletter Topics

Named subscription topics that contacts can opt in or out of (Morning Boost, Campaigns, Product Updates, etc.).

GET/api/admin/newsletter-topicsAdmin

List topics

curl
curl https://fixernation.org/api/admin/newsletter-topics \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/newsletter-topicsAdmin

Create a topic

Request Body

NameTypeRequiredDescription
namestringYesDisplay name
slugstringYesURL-safe slug used in subscribe/unsubscribe links
descriptionstringNoSubscriber-facing description
defaultOptInbooleanNoWhether new contacts are opted in by default (default false)
curl
curl -X POST https://fixernation.org/api/admin/newsletter-topics \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Monthly Newsletter","slug":"monthly-newsletter","defaultOptIn":false}'
PUT/api/admin/newsletter-topics/:idAdmin

Update a topic

curl
curl -X PUT https://fixernation.org/api/admin/newsletter-topics/topic1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"defaultOptIn":true}'
DELETE/api/admin/newsletter-topics/:idAdmin

Delete a topic

curl
curl -X DELETE https://fixernation.org/api/admin/newsletter-topics/topic1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>"

Custom Fields

Admin-defined contact fields beyond the built-in properties. Support text, number, date, boolean, and dropdown types.

GET/api/admin/custom-fieldsAdmin

List custom field definitions

curl
curl https://fixernation.org/api/admin/custom-fields \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/custom-fieldsAdmin

Create a custom field

Request Body

NameTypeRequiredDescription
labelstringYesField display name
keystringYesInternal snake_case key (also used as {{variable}} in templates)
typestringYestext | number | date | boolean | dropdown
optionsstring[]NoAllowed values (dropdown type only)
requiredbooleanNoWhether required on contact creation
curl
curl -X POST https://fixernation.org/api/admin/custom-fields \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"label":"Membership Tier","key":"membership_tier","type":"dropdown","options":["Bronze","Silver","Gold"]}'
PUT/api/admin/custom-fields/:idAdmin

Update a field definition

Note: The field type cannot be changed after creation. Only label, options, and required can be updated.
curl
curl -X PUT https://fixernation.org/api/admin/custom-fields/def1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"options":["Bronze","Silver","Gold","Platinum"]}'
DELETE/api/admin/custom-fields/:idAdmin

Deactivate a custom field

Note: Fields are soft-deleted so historical values are preserved.
curl
curl -X DELETE https://fixernation.org/api/admin/custom-fields/def1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>"

Suppression

The suppression list tracks addresses that should never receive emails: hard bounces, spam complaints, one-click unsubscribes, and manual admin blocks.

GET/api/admin/suppressionAdmin

List suppression records

Query Parameters

NameTypeRequiredDescription
qstringNoSearch by email
reasonstringNoBOUNCE | COMPLAINT | UNSUBSCRIBE | ADMIN
pagenumberNoPage number
curl
curl "https://fixernation.org/api/admin/suppression?reason=BOUNCE" \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/suppressionAdmin

Add a suppression

Request Body

NameTypeRequiredDescription
emailstringYesEmail to suppress
reasonstringYesADMIN for manual adds; others are set automatically
notestringNoInternal note
curl
curl -X POST https://fixernation.org/api/admin/suppression \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"email":"jane@example.com","reason":"ADMIN","note":"Customer requested"}'
DELETE/api/admin/suppression/:idAdmin

Lift a suppression

Note: Re-enables email delivery to that address. Use with care.
curl
curl -X DELETE https://fixernation.org/api/admin/suppression/sup1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>"

Users

Platform user management. Role promotion requires SUPER_ADMIN privileges.

PATCH/api/admin/users/:idSuper Admin

Update a user's role

Only SUPER_ADMINs can assign or remove ADMIN and SUPER_ADMIN roles. A SUPER_ADMIN cannot change their own role.

Note: Attempting to assign ADMIN or SUPER_ADMIN as a plain ADMIN returns 403.

Request Body

NameTypeRequiredDescription
rolestringYesCONSUMER | MEMBER | PROVIDER | AMBASSADOR | ADMIN | SUPER_ADMIN
curl
curl -X PATCH https://fixernation.org/api/admin/users/usr1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"role":"ADMIN"}'

Applications

Service provider and brand ambassador applications submitted through the public onboarding forms.

GET/api/admin/applicationsAdmin

List applications

Query Parameters

NameTypeRequiredDescription
typestringNoPROVIDER or AMBASSADOR
statusstringNoPENDING | UNDER_REVIEW | APPROVED | REJECTED | INVITED | ONBOARDED | SPAM
qstringNoSearch by name or email
pagenumberNoPage number
curl
curl "https://fixernation.org/api/admin/applications?status=PENDING&type=PROVIDER" \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
GET/api/admin/applications/:idAdmin

Get an application with all fields

curl
curl https://fixernation.org/api/admin/applications/app1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
PUT/api/admin/applications/:idAdmin

Update application status or notes

Request Body

NameTypeRequiredDescription
statusstringNoUNDER_REVIEW | APPROVED | REJECTED
adminNotesstringNoInternal notes
rejectionReasonstringNoReason shown to applicant on rejection
curl
curl -X PUT https://fixernation.org/api/admin/applications/app1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"status":"APPROVED","adminNotes":"Verified 2026-08-16"}'
POST/api/admin/applications/invite/:idAdmin

Send platform invitation to an approved applicant

Note: Requires APPROVED status. Sends a time-limited invite link and changes status to INVITED.
curl
curl -X POST https://fixernation.org/api/admin/applications/invite/app1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/applications/payment/:idAdmin

Record a manual payment

Request Body

NameTypeRequiredDescription
amountnumberYesAmount in dollars
methodstringYescheck, wire, cash, etc.
notesstringNoPayment reference or notes
curl
curl -X POST https://fixernation.org/api/admin/applications/payment/app1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"amount":250,"method":"check","notes":"Check #1042"}'
PUT/api/admin/applications/directory/:idAdmin

Toggle provider directory listing

Request Body

NameTypeRequiredDescription
directoryListedbooleanYestrue = visible in provider directory
curl
curl -X PUT https://fixernation.org/api/admin/applications/directory/app1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"directoryListed":true}'

Community Groups

Social groups that members can join, post in, and discuss topics. Groups can be PUBLIC or PRIVATE.

GET/api/admin/groupsAdmin

List community groups

curl
curl https://fixernation.org/api/admin/groups \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/groupsAdmin

Create a group

Request Body

NameTypeRequiredDescription
namestringYesGroup name
slugstringYesUnique URL slug
descriptionstringNoGroup description
visibilitystringNoPUBLIC (default) or PRIVATE
coverUrlstringNoCloudinary cover image URL
curl
curl -X POST https://fixernation.org/api/admin/groups \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Mindset and Growth","slug":"mindset-growth","visibility":"PUBLIC"}'
PATCH/api/admin/groups/:idAdmin

Update a group

curl
curl -X PATCH https://fixernation.org/api/admin/groups/grp1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"description":"A group about mindset and personal growth."}'
PUT/api/admin/groups/:id/requestsAdmin

Approve or reject join requests

Request Body

NameTypeRequiredDescription
requestIdstringYesJoin request ID
actionstringYesapprove or reject
curl
curl -X PUT https://fixernation.org/api/admin/groups/grp1/requests \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"requestId":"req1","action":"approve"}'

Content

Blog posts, Morning Boost entries, Events, and Resources all follow the same REST pattern. Examples below use /api/admin/blog — substitute morning-boost, events, or resources for the other types.

GET/api/admin/blogAdmin

List blog posts

Query Parameters

NameTypeRequiredDescription
qstringNoSearch by title
publishedbooleanNotrue = published only, false = drafts only
curl
curl https://fixernation.org/api/admin/blog \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/blogAdmin

Create a blog post

Note: Use POST /api/admin/blog/upload to get a Cloudinary signed URL before setting imageUrl. The same pattern applies for morning-boost and resources.

Request Body

NameTypeRequiredDescription
titlestringYesPost title
slugstringYesUnique URL slug
contentstringNoHTML or Markdown body
excerptstringNoShort summary for cards and meta
imageUrlstringNoCloudinary featured image URL
categorystringNoCategory label
authorNamestringNoByline
publishedAtstringNoISO 8601 publish date; null keeps it as a draft
curl
curl -X POST https://fixernation.org/api/admin/blog \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"title":"Five Mindset Habits","slug":"five-mindset-habits","authorName":"Anthony J. Placito","publishedAt":"2026-08-16T10:00:00.000Z"}'
PUT/api/admin/blog/:idAdmin

Update a blog post

curl
curl -X PUT https://fixernation.org/api/admin/blog/post1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"title":"Updated Title"}'
DELETE/api/admin/blog/:idAdmin

Delete a blog post

curl
curl -X DELETE https://fixernation.org/api/admin/blog/post1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/blog/uploadAdmin

Get a signed Cloudinary upload URL

Returns a pre-signed URL and parameters for a direct browser-to-Cloudinary image upload. After upload, the returned secure_url becomes the imageUrl.

Response
{
  "uploadUrl": "https://api.cloudinary.com/v1_1/your-cloud/image/upload",
  "signature": "abc123",
  "timestamp": 1700000000,
  "apiKey": "your-api-key",
  "folder": "blog"
}
curl
curl -X POST https://fixernation.org/api/admin/blog/upload \
  -H "Cookie: __Secure-next-auth.session-token=<token>"

Products & Gift Codes

Products and their prices sync to Stripe. Gift codes grant membership access on redemption.

GET/api/admin/productsAdmin

List products

curl
curl https://fixernation.org/api/admin/products \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/productsAdmin

Create a product

Request Body

NameTypeRequiredDescription
namestringYesProduct name
descriptionstringNoDescription
imageUrlstringNoCover image URL
categorystringNobook, membership, event, etc.
curl
curl -X POST https://fixernation.org/api/admin/products \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Annual Membership","category":"membership"}'
POST/api/admin/products/:id/pricesAdmin

Add a price to a product

Request Body

NameTypeRequiredDescription
amountnumberYesPrice in cents
currencystringNoCurrency code (default usd)
intervalstringNomonth or year (recurring); omit for one-time
labelstringNoDisplay label (Monthly, Annual, etc.)
curl
curl -X POST https://fixernation.org/api/admin/products/prod1/prices \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"amount":4900,"currency":"usd","interval":"month","label":"Monthly"}'
POST/api/admin/products/:id/stripe-syncAdmin

Sync product and prices to Stripe

Note: Creates or updates the Stripe Product and Price objects. Requires STRIPE_SECRET_KEY to be configured.
curl
curl -X POST https://fixernation.org/api/admin/products/prod1/stripe-sync \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
GET/api/admin/gift-codesAdmin

List gift codes

Query Parameters

NameTypeRequiredDescription
usedbooleanNoFilter by used / unused status
curl
curl "https://fixernation.org/api/admin/gift-codes?used=false" \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/gift-codesAdmin

Generate a batch of gift codes

Request Body

NameTypeRequiredDescription
countnumberYesNumber to generate (1–1000)
grantRolestringYesRole granted on redemption (MEMBER)
expiresAtstringNoISO 8601 expiry; null for no expiry
notesstringNoInternal batch notes
curl
curl -X POST https://fixernation.org/api/admin/gift-codes \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"count":25,"grantRole":"MEMBER","notes":"Conference 2026"}'

Settings

Key-value settings stored in the database. Used for site-wide configuration including logo URL, site name, and email sender defaults.

GET/api/admin/settingsAdmin

Get all settings

Response
{
  "settings": {
    "site_name": "Fixer Nation",
    "site_logo_url": null,
    "morning_boost_from_name": "Fixer Nation",
    "morning_boost_from_email": "noreply@fixernation.org"
  }
}
curl
curl https://fixernation.org/api/admin/settings \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
PUT/api/admin/settingsAdmin

Update a setting

Note: One key-value pair per request.

Request Body

NameTypeRequiredDescription
keystringYesSetting key
valuestringYesNew value
curl
curl -X PUT https://fixernation.org/api/admin/settings \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"key":"site_logo_url","value":"https://res.cloudinary.com/fn/logo.png"}'

Territories

Geographic territories for organizing ambassador and provider coverage areas.

GET/api/admin/territoriesAdmin

List territories

curl
curl https://fixernation.org/api/admin/territories \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/admin/territoriesAdmin

Create a territory

Request Body

NameTypeRequiredDescription
namestringYesTerritory name (e.g. Greater Austin)
statestringNoState abbreviation
regionstringNoBroader region label
curl
curl -X POST https://fixernation.org/api/admin/territories \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Greater Austin","state":"TX"}'
PUT/api/admin/territories/:idAdmin

Update or delete a territory

Note: Use DELETE to remove. Territories with assigned ambassadors or providers cannot be deleted.
curl
curl -X PUT https://fixernation.org/api/admin/territories/terr1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Austin Metro"}'

Affiliates & Commissions

Affiliates are ambassador accounts with commission tracking. Commissions are generated by referrals and reviewed by admins.

GET/api/admin/affiliatesAdmin

List affiliates

Query Parameters

NameTypeRequiredDescription
qstringNoSearch by name or email
curl
curl https://fixernation.org/api/admin/affiliates \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
GET/api/admin/affiliates/:idAdmin

Get an affiliate with commission history

curl
curl https://fixernation.org/api/admin/affiliates/aff1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
PATCH/api/admin/commissions/:idAdmin

Approve, reject, or mark a commission paid

Request Body

NameTypeRequiredDescription
statusstringYesAPPROVED | REJECTED | PAID
notesstringNoInternal note
curl
curl -X PATCH https://fixernation.org/api/admin/commissions/comm1 \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"status":"APPROVED"}'

Memberships

GET/api/admin/membershipsAdmin

List active Stripe subscriptions

Returns subscription records synced from Stripe. Use the Stripe dashboard for full subscription management.

Query Parameters

NameTypeRequiredDescription
qstringNoSearch by email or Stripe customer ID
statusstringNoactive | past_due | canceled | trialing
curl
curl "https://fixernation.org/api/admin/memberships?status=active" \
  -H "Cookie: __Secure-next-auth.session-token=<token>"

Provider APIs

Providers have their own isolated CRM. Provider contacts are completely separate from the platform contact table and cannot be used for FN-originated sends.

GET/api/provider/contactsAdmin

List contacts (authenticated provider only)

Note: Returns only contacts owned by the authenticated PROVIDER user.
curl
curl https://fixernation.org/api/provider/contacts \
  -H "Cookie: __Secure-next-auth.session-token=<token>"
POST/api/provider/contactsAdmin

Add a contact to the provider's CRM

Request Body

NameTypeRequiredDescription
emailstringYesContact email
firstNamestringNoFirst name
lastNamestringNoLast name
phonestringNoPhone number
notesstringNoPrivate notes
curl
curl -X POST https://fixernation.org/api/provider/contacts \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"email":"client@example.com","firstName":"Bob"}'
POST/api/provider/campaignsAdmin

Create a provider campaign

Note: Provider campaigns can only target the provider's own contacts. FN contact lists are not accessible.

Request Body

NameTypeRequiredDescription
namestringYesCampaign name
subjectstringYesEmail subject line
htmlBodystringYesEmail HTML content
fromEmailstringYesProvider's sender email
curl
curl -X POST https://fixernation.org/api/provider/campaigns \
  -H "Cookie: __Secure-next-auth.session-token=<token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Summer Promo","subject":"Special Offer","htmlBody":"<p>Hello...</p>","fromEmail":"hello@provider.com"}'

Public APIs

Unauthenticated endpoints for public-facing actions including newsletter subscriptions and one-click unsubscribes from email links.

POST/api/public/subscribePublic

Subscribe to a newsletter topic

Finds or creates a Contact by email and sets consent for the given topic. Safe to call multiple times for the same email.

Request Body

NameTypeRequiredDescription
emailstringYesSubscriber email address
firstNamestringNoFirst name (sets contact name on first subscribe)
topicstringYesNewsletter topic slug
sourcestringNoSource context (web-form, landing-page, etc.)
Response
{"message":"Subscribed successfully.","contactId":"clx1abc"}
curl
curl -X POST https://fixernation.org/api/public/subscribe \
  -H "Content-Type: application/json" \
  -d '{"email":"jane@example.com","firstName":"Jane","topic":"monthly-newsletter"}'
GET/api/public/unsubscribePublic

One-click unsubscribe from an email

Called via the unsubscribe link in campaign emails. The signed token encodes the contact ID and topic.

Query Parameters

NameTypeRequiredDescription
tokenstringYesSigned token from the email's unsubscribe link
Response
{"message":"You have been unsubscribed."}
curl
curl "https://fixernation.org/api/public/unsubscribe?token=SIGNED_TOKEN"

Webhooks

Inbound webhooks from third-party services. These endpoints do not require a user session but validate request signatures.

POST/api/webhooks/stripePublic

Stripe subscription lifecycle events

Receives events for subscription creation, updates, and cancellations. Validates the Stripe-Signature header using STRIPE_WEBHOOK_SECRET.

Note: Configure this URL in Stripe: Developers > Webhooks. Handled events: checkout.session.completed, customer.subscription.updated, customer.subscription.deleted.
curl
# Stripe calls this automatically.
# Test locally with the Stripe CLI:
stripe listen --forward-to https://fixernation.org/api/webhooks/stripe
Fixer Nation API Reference — for support contact admin@fixernation.org