Guides and tools
Publisher MCP
Create article requests, check progress, collect offer links, and review your earnings.
Server URLhttps://lp.thriftler.com/mcp/portal
Connect your assistant
MCP lets an assistant call AFFMAX tools using your account permissions. Use a client that supports remote HTTP MCP servers and bearer authentication.
- Create a publisher token in Account Settings > API Access in the publisher portal. New portal tokens include both read and submit permissions.
- Add the server URL above to your client and set
Authorization: Bearer YOUR_TOKEN. ReplaceYOUR_TOKENwith your token. - Reconnect the client to load the tool list. Keep the token in your client's secret configuration.
Example configuration for clients that accept mcpServers JSON. Your client's settings format may differ.
{
"mcpServers": {
"affmax-publisher": {
"url": "https://lp.thriftler.com/mcp/portal",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}
For integrations, the tool catalog JSON contains the registered tool definitions and input schemas. Your connected client discovers these through MCP tools/list.
Permissions
network:read- Connect, discover forms, check submissions, and read your offers, links, conversions, statements, and earnings.
network:submit- Submit individual or batch form requests. Also requires network:read.
Use a publisher token from the portal.
Submitting a form starts work immediately under the network's published workflow. Read the form's documentation and required inputs before submitting.
Create offers and collect links
Ask your assistant to create individual or batch article requests through a published form. Article generation runs in the background. Keep the returned submission and batch IDs to check progress later.
Create two US articles in English: home insulation and solar savings. Use a separate offer name for each. Check progress and give me the offer tracking links as they become ready.
The examples below show the params object of an MCP tools/call request. Your MCP client handles the protocol envelope and authentication. IDs, fields, and results are illustrative; use the form returned for your account.
1. Discover the form
Call list_forms with {}, then get_form with its form_id. Read the required fields, select options, and documentation. Form IDs and schemas vary by network. Only submit when supports_api_submission is true; forms with file uploads require the portal.
{
"name": "get_form",
"arguments": {
"form_id": 5
}
}
2. Submit one request or a batch
Use submit_form for one request. This example assumes the discovered article form declares these fields.
{
"name": "submit_form",
"arguments": {
"form_id": 5,
"idempotency_key": "article-insulation-001",
"inputs": {
"marketing_angle": "How insulation helps reduce home energy costs",
"funnel_name": "US Home Insulation",
"target_language": "en",
"target_geo": "US"
}
}
}
For multiple requests, use submit_form_batch instead. A batch accepts 1 to 10 items for one form. Give each item a unique reference so you can match its result to your request.
{
"name": "submit_form_batch",
"arguments": {
"form_id": 5,
"idempotency_key": "article-batch-001",
"items": [
{
"reference": "insulation-us",
"inputs": {
"marketing_angle": "How insulation helps reduce home energy costs",
"funnel_name": "US Home Insulation",
"target_language": "en",
"target_geo": "US"
}
},
{
"reference": "solar-us",
"inputs": {
"marketing_angle": "What homeowners should know about solar savings",
"funnel_name": "US Solar Savings",
"target_language": "en",
"target_geo": "US"
}
}
]
}
}
3. Check progress
For one request, call get_submission with the returned submission_id. For a batch, call get_submission_batch with its batch_id. Wait the returned poll_after_seconds between checks, currently 30 seconds while processing.
{
"name": "get_submission_batch",
"arguments": {
"batch_id": "5c3a0fc1-67a6-4b93-9ae0-e23596f41b82"
}
}
Batch responses include counts by state and each item's status. Completed items include their available offer links even while other items are still running. Stop polling when finished is true.
4. Collect the offer links
Read items[].offers[] from a batch, or offers[] from a single submission. Save the offer ID and tracking_url with the item's reference. Example excerpt from a completed item's offers array:
[
{
"hosted_offer_id": 123,
"name": "US Home Insulation",
"tracking_url": "https://track.example.com/c/AB12CD34/EF56GH78",
"link_status": "ready"
}
]
Send traffic through the returned tracking_url. If it is null and link_status is not_configured, ask your operator to configure the tracking domain. A completed request can have no offers if its workflow creates none or access has been revoked.
After reconnecting, call list_submissions to recover recent requests and batch IDs, including requests from the portal or REST API. Pass next_before_id as before_id to get the next page. Use get_tracking_link with the saved offer ID to retrieve a current link later.
Status and retries
queued- Accepted and waiting to start.
running- Generation or another workflow step is in progress.
waiting/paused- Waiting for review or paused by the workflow. Keep the same submission; contact your operator if it needs attention.
completed- The request finished. Collect any available offer links.
failed- The request stopped with an error. Contact your operator with its submission ID before creating a replacement.
A batch is processing until its requests finish, then completed, completed_with_errors, or failed. Results follow the network's retention policy. A finished batch with removed results is expired and includes an unavailable count. Save ready links in your own system.
- Retry a lost response: reuse the same
idempotency_keyand identical inputs or items. You receive the original IDs. A reserved key with changed inputs is rejected. Keys allow up to 128 characters; single and batch keys are separate. - Validation and limits: all batch items are validated before any are accepted. Invalid or over-limit batches start no requests. Single and batch submissions share a limit of 10 requests per publisher per form per hour; network-wide limits also apply.
- Partial failure: accepted items run independently. One failure does not discard completed links. A failed request may already have performed work, so do not automatically resubmit with a fresh key.
For the equivalent HTTP endpoints and form-specific schemas, see Forms API and MCP.
Troubleshooting
- Cannot connect: check the server URL, bearer header, and token. Publisher and team tokens belong to different servers. Revoked tokens must be replaced.
- Permission denied: check the abilities above and your account's access. Seeing a tool in the list does not grant permission to call it.
- Invalid arguments: use the tool's input schema below and the error's field details to correct the request.
Tool reference
Names, descriptions, and schemas come from the registered tools. Open a tool to inspect its arguments and complete JSON Schema.
13 tools
get_formArguments
Get a published request form, its required fields, defaults, choices, conditions, and instructions. Use these definitions for submit_form or submit_form_batch; form IDs and fields are discovered, not hardcoded.
form_idinteger · required- Form ID from list_forms.
Full input schema
{
"properties": {
"form_id": {
"description": "Form ID from list_forms.",
"type": "integer"
}
},
"type": "object",
"required": [
"form_id"
]
}
get_offerArguments
Get one of your approved hosted offers in full detail (payout terms, tracking link, variations, guidelines).
hosted_offer_idinteger · required- The hosted offer to fetch.
Full input schema
{
"properties": {
"hosted_offer_id": {
"description": "The hosted offer to fetch.",
"type": "integer"
}
},
"type": "object",
"required": [
"hosted_offer_id"
]
}
get_submissionArguments
Check your request status: queued, running, waiting for review, paused, completed, or failed. Completed requests include approved offers and tracking_url values. Respect poll_after_seconds (30 while unfinished). Article generation can take several minutes; a pending request is not a reason to resubmit.
submission_idinteger · required- Your submission ID from a single or batch request.
Full input schema
{
"properties": {
"submission_id": {
"description": "Your submission ID from a single or batch request.",
"type": "integer"
}
},
"type": "object",
"required": [
"submission_id"
]
}
get_submission_batchArguments
Check one of your batches. Returns aggregate counts and every item with its reference, submission ID, status, and completed offer tracking links. Completed links are available while other items are still running. Respect poll_after_seconds and stop polling when finished is true; completed_with_errors means some items failed.
batch_idstring · required- Batch UUID returned by submit_form_batch.
Full input schema
{
"properties": {
"batch_id": {
"description": "Batch UUID returned by submit_form_batch.",
"type": "string"
}
},
"type": "object",
"required": [
"batch_id"
]
}
get_tracking_linkArguments
Get the tracking link(s) for one of your approved offers: the base link and, optionally, one variation link.
hosted_offer_idinteger · required- The approved hosted offer.
variation_keystring · optional- Optional variation key to get a single variation link instead of the full list.
Full input schema
{
"properties": {
"hosted_offer_id": {
"description": "The approved hosted offer.",
"type": "integer"
},
"variation_key": {
"description": "Optional variation key to get a single variation link instead of the full list.",
"type": "string"
}
},
"type": "object",
"required": [
"hosted_offer_id"
]
}
list_conversionsArguments
List your conversions in a date window (payout, status, sub ids). Held conversions show as pending.
fromstring · required- Start date (Y-m-d), UTC.
tostring · required- End date (Y-m-d), inclusive, UTC.
statusstring · optional- Optional: pending, approved, rejected, or reversed.
pageinteger · optional- Page number (default 1).
page_sizeinteger · optional- Rows per page (default 500, max 500).
Full input schema
{
"properties": {
"from": {
"description": "Start date (Y-m-d), UTC.",
"type": "string"
},
"to": {
"description": "End date (Y-m-d), inclusive, UTC.",
"type": "string"
},
"status": {
"description": "Optional: pending, approved, rejected, or reversed.",
"type": "string"
},
"page": {
"description": "Page number (default 1).",
"type": "integer"
},
"page_size": {
"description": "Rows per page (default 500, max 500).",
"type": "integer"
}
},
"type": "object",
"required": [
"from",
"to"
]
}
list_formsArguments
Discover request forms available to your publisher account, including article requests. Returns field definitions, documentation, and batch limits. Read the form before submitting.
This tool takes no arguments. Pass an empty object: {}.
Full input schema
{
"type": "object",
"properties": {}
}
list_offersArguments
List your approved hosted offers with payout terms and tracking links.
pageinteger · optional- Page number (default 1).
page_sizeinteger · optional- Rows per page (default 100, max 100).
Full input schema
{
"properties": {
"page": {
"description": "Page number (default 1).",
"type": "integer"
},
"page_size": {
"description": "Rows per page (default 100, max 100).",
"type": "integer"
}
},
"type": "object"
}
list_statementsArguments
List your statements, or pass statement_id to get one statement with its line items.
statement_idinteger · optional- Optional: fetch one statement with its line items instead of the list.
Full input schema
{
"properties": {
"statement_id": {
"description": "Optional: fetch one statement with its line items instead of the list.",
"type": "integer"
}
},
"type": "object"
}
list_submissionsArguments
List your recent form requests (including portal, REST, and MCP submissions), newest first, with status, batch IDs, and approved offer links. Recover request handles after reconnecting. Pass next_before_id as before_id to fetch the next page.
form_idinteger · optional- Optional form filter.
before_idinteger · optional- Cursor from the preceding response next_before_id.
limitinteger · optional- Page size, default 25, maximum 100.
Full input schema
{
"properties": {
"form_id": {
"description": "Optional form filter.",
"type": "integer"
},
"before_id": {
"description": "Cursor from the preceding response next_before_id.",
"type": "integer"
},
"limit": {
"description": "Page size, default 25, maximum 100.",
"minimum": 1,
"maximum": 100,
"type": "integer"
}
},
"type": "object"
}
my_statsArguments
Your clicks, approved conversions + payout for a date window, plus month-to-date earnings.
fromstring · required- Start date (Y-m-d), UTC.
tostring · required- End date (Y-m-d), inclusive, UTC.
Full input schema
{
"properties": {
"from": {
"description": "Start date (Y-m-d), UTC.",
"type": "string"
},
"to": {
"description": "End date (Y-m-d), inclusive, UTC.",
"type": "string"
}
},
"type": "object",
"required": [
"from",
"to"
]
}
submit_formArguments
Submit one published request form. Requires network:submit and starts real work (article generation and offer creation for an article form). Returns immediately with a submission ID; poll get_submission for status and approved tracking links. Reuse the same idempotency_key and inputs on retries; use a new key only for a new request.
form_idinteger · required- Form ID from list_forms.
inputsobject · required- Declared field values from get_form.
idempotency_keystring · required- Unique request key, at most 128 characters. Keep unchanged on retries.
Full input schema
{
"properties": {
"form_id": {
"description": "Form ID from list_forms.",
"type": "integer"
},
"inputs": {
"description": "Declared field values from get_form.",
"type": "object"
},
"idempotency_key": {
"description": "Unique request key, at most 128 characters. Keep unchanged on retries.",
"type": "string"
}
},
"type": "object",
"required": [
"form_id",
"inputs",
"idempotency_key"
]
}
submit_form_batchArguments
Submit up to 10 requests to one published form. Requires network:submit; starts real work. Each item has a unique reference and inputs. The entire batch is validated and accepted atomically, subject to the shared 10 requests per publisher/form/hour limit. Returns a durable batch_id and submission IDs; poll get_submission_batch for per-item progress and completed offer links. Keep the same idempotency_key and items on retries.
form_idinteger · required- Form ID from list_forms. All items use this form.
itemsarray · required- See the full schema for accepted values.
idempotency_keystring · required- Unique batch request key, at most 128 characters. Keep unchanged on retries.
Full input schema
{
"properties": {
"form_id": {
"description": "Form ID from list_forms. All items use this form.",
"type": "integer"
},
"items": {
"minItems": 1,
"maxItems": 10,
"items": {
"properties": {
"reference": {
"description": "Your unique item label, at most 100 characters.",
"type": "string"
},
"inputs": {
"description": "Declared field values from get_form.",
"type": "object"
}
},
"type": "object",
"required": [
"reference",
"inputs"
]
},
"type": "array"
},
"idempotency_key": {
"description": "Unique batch request key, at most 128 characters. Keep unchanged on retries.",
"type": "string"
}
},
"type": "object",
"required": [
"form_id",
"items",
"idempotency_key"
]
}
No tools match your search. Try a tool name such as get_form.