All guides

MIGRATE KEAP FROM XML-RPC TO REST v2 BEFORE THE SUNSET

Keap is turning off its oldest API. If anything you run touches Keap through XML-RPC — and you might not know it does — it stops on the sunset date. Here is what actually changes, and the one opt-in detail that quietly makes migrated contacts non-marketable.

Keap / XML-RPC → REST v2 / Intermediate / 9 min read

THE DEADLINE, AND WHY IT IS FUZZIER THAN IT SHOULD BE

Keap announced it is retiring the XML-RPC API and moving everyone to REST v2. The officially announced date is December 31, 2026 — after which XML-RPC calls stop, with no grace period. Through 2026 there are scheduled brownouts: short, deliberate outages of XML-RPC that get longer as the year goes on, so your integration fails in a controlled window instead of failing for real on New Year's Day.

The date has been muddier than a hard deadline should be. Some partners received emails in 2026 citing a 2027 sunset; Keap called that an error. Meanwhile there is real pressure to push the date, because REST v2 still has missing pieces developers keep hitting mid-migration. None of that is a reason to relax.

Plan against December 31, 2026. But before you commit a client to a hard date, confirm the current one against Keap's own XML-RPC sunset article and the brownout schedule. A date hardcoded into a guide is exactly the thing that goes stale.

FIRST, FIND OUT IF THIS EVEN TOUCHES YOU

The people most exposed here are the ones who do not think they are. XML-RPC is old enough that it is buried inside things — a Zapier connection, a plugin a developer installed years ago, a script nobody has looked at since it started working. The owner has no idea any of it speaks XML-RPC, because it just quietly runs.

So the first job is inventory, not code. Two passes:

Keap also publishes an integrator status report so you can see whether your own app is still sending XML-RPC traffic. Start there before you assume you are clear.

WHAT ACTUALLY CHANGES

This is not a version bump. XML-RPC and REST v2 are different shapes, and four things change at once.

shapebefore → after
// XML-RPC (before): one endpoint, method named in the body
POST /crm/xmlrpc/v1
  method: ContactService.add
  params: [ apiKey, { FirstName, Email } ]

// REST v2 (after): a resource, a verb, an OAuth bearer token
POST /crm/rest/v2/contacts
  Authorization: Bearer <access_token>
  { "given_name": "Jane", "email_addresses": [ ... ] }

The base URL moves from api.infusionsoft.com/crm/xmlrpc/v1 to api.infusionsoft.com/crm/rest/v2, and the full parameter and response shapes for every endpoint live in the REST v2 documentation.

THE MAPPING IS NOT ONE-TO-ONE

Most XML-RPC methods have a clean REST v2 equivalent, and Keap publishes a method-to-endpoint mapping that saves you the guesswork. Use it. But do not assume the mapping is total.

A set of XML-RPC methods are not being converted at all, and as of mid-2026, developers migrating real integrations were still finding gaps and limitations as they went. The practical consequence: check the gap list before you scope the work, not during it. If a method you depend on has no REST v2 home yet, that is a sequencing decision to make on day one — flag it, raise it in the developer forum, and do the calls that do map first while the gap gets resolved.

THE GOTCHA THAT MAKES CONTACTS NON-MARKETABLE

This is the one that cost us time, so it is the one worth handing you. When you create or update a contact in REST v2 and you set an opt-in reason, where you put it matters more than what you put.

The XML-RPC-era instinct is to treat the opt-in as a property of the contact. In REST v2 the email address is its own object inside an email_addresses array, and the opt-in reason has to be nested inside that email object. Put it at the top level and the request still succeeds — the contact saves, you get a 200, nothing looks wrong. But the contact lands non-marketable, which means every campaign and broadcast silently skips it. You do not find out from an error. You find out weeks later when a send goes to fewer people than it should have.

contactsthe opt-in nesting
// WRONG — opt_in_reason at the top level (the v1 habit).
// Saves fine, returns 200, lands NON-MARKETABLE.
{
  "given_name": "Jane",
  "email_addresses": [{ "email": "jane@acme.com", "field": "EMAIL1" }],
  "opt_in_reason": "Imported from prior system"
}

// RIGHT — opt_in_reason nested INSIDE the email object.
{
  "given_name": "Jane",
  "email_addresses": [{
    "email": "jane@acme.com",
    "field": "EMAIL1",
    "opt_in_reason": "Imported from prior system"
  }]
}

Why it bites: the failure is silent. A non-marketable contact is not an error you can catch in code — it is a state you have to go looking for. If you are migrating a contact import, spot-check the marketable status of the first batch before you run the other ten thousand.

HANDLE THE ERRORS REST ACTUALLY GIVES YOU

XML-RPC handed back generic faults, so most integrations treated every failure the same way. REST v2 returns real HTTP status codes, which means you can — and should — branch on them:

The single highest-value thing to centralize is token handling: refresh in one place, so a 401 anywhere in your integration heals itself instead of taking down whichever call happened to hit the expiry.

VALIDATE AGAINST THE OLD CALLS, NOT AGAINST HOPE

The migration is done when the new calls return the same information the old ones did — not when they return something. Keep the XML-RPC responses around and compare field by field: are the mandatory fields populated, are dates and numbers in the format REST expects, did anything the old call returned quietly drop out of the new one.

And use the brownouts on purpose. They are free production-condition tests: during a brownout, XML-RPC is down, so anything that breaks is something you still have not migrated. That is the cheapest possible way to discover a dependency you missed — far cheaper than discovering it on January 1.

USE THE SDKS, OR AT LEAST KNOW THEY EXIST

Keap maintains official SDKs generated from the REST v2 OpenAPI spec, in several languages, in the keap-sdk repository. If your stack matches one, they handle a lot of the request and response plumbing for you. If you would rather use a plain HTTP client, that is fine too — you just own the headers, pagination, and error handling yourself. Either way, knowing the SDKs exist beats reinventing them by accident.

COMMON QUESTIONS

When does XML-RPC actually stop working?

The officially announced sunset is December 31, 2026, with brownouts throughout 2026 and the final one in early December. Some 2027 emails went out and were called an error, and there is community pressure to extend the date because REST v2 still has gaps — so plan against December 31, 2026 and verify the current date before betting a deadline on it.

How do I know if I even use XML-RPC?

Search your code for the /crm/xmlrpc/v1 endpoint and audit every third-party tool wired to Keap. Most owners who use it use it indirectly — through a Zapier connection or an old plugin — and have no idea. If you cannot account for an integration, assume it is affected until proven otherwise.

Do I have to migrate everything at once?

No. Both APIs run in parallel until the sunset, so migrate one call at a time: move it, validate it against the old response, ship it, repeat. A staged migration is lower-risk than a big-bang rewrite, and there is no reason to take the bigger risk.

Why did my migrated contacts become non-marketable?

Because opt_in_reason was sent at the top level of the contact instead of nested inside the email address object. The request succeeds, but the contact lands non-marketable and campaigns silently skip it. Nest the opt-in inside the email object and spot-check marketable status before a bulk import.

What if a REST v2 endpoint I need does not exist yet?

A small set of methods are not being converted, and gaps were still surfacing mid-2026. Check that list before scoping, do the calls that map first, and flag anything with no equivalent in the developer forum rather than discovering it at the deadline.

MIGRATING AND WOULD RATHER NOT DO IT ALONE?

We build and maintain Keap integrations for a living, and we have already run this migration — including the parts that fail silently. If you would rather hand it off, or just want a second set of eyes before the sunset, that is what the consult is for.

Book a Free Consult