Recipes

Handle a retired IX ID

Tell a retired item, which still resolves and points to its successor, from a withdrawn one, which must not be shown at all.

This is a worked example, not a supported connector. Interchange does not build or run connectors. You own the code you write from it, and the support boundary applies. Read the support boundary.

This recipe needs no key.

How it works

  1. A retired item still answers

    The call returns 200 with status of retired and replaced_by. Follow the pointer and store the new ID, so you stop asking about the old one.

  2. A withdrawn item answers 410

    It was withdrawn, usually because its mapping was wrong or unsafe. Do not show it. If the problem body has replaced_by, that is the correction.

  3. An unknown ID answers 404

    That ID never existed. Check where it came from. Do not treat it as withdrawn.

  4. Cap the chain

    A replacement can itself be replaced. Follow a few hops, then stop and ask a person, rather than loop.

The code

Node 22, no libraries. Adapt it to your language and your storage.

JavaScript: resolve a stored IX ID
const BASE = "https://api.interchangeparts.com.au";
const KEY = process.env.INTERCHANGE_API_KEY; // only the keyed endpoints need it

async function call(path, init = {}) {
  const response = await fetch(BASE + path, {
    ...init,
    headers: { Accept: "application/json", ...(KEY ? { Authorization: "Bearer " + KEY } : {}), ...init.headers },
  });
  // Errors are application/problem+json, success is application/json. Both parse as JSON.
  return { status: response.status, body: await response.json(), requestId: response.headers.get("Interchange-Request-Id") };
}

// Returns what to show for an IX ID you have stored, and the ID to store from now on.
export async function resolveItem(ixId, hops = 0) {
  const { status, body, requestId } = await call("/v1/items/" + encodeURIComponent(ixId));

  if (status === 410) {
    // Withdrawn: never show it. If a corrected item replaces it, replaced_by says which.
    return { show: null, store: body.replaced_by ?? null, reason: "withdrawn" };
  }
  if (status === 404) return { show: null, store: null, reason: "unknown id" }; // an ID that never existed
  if (status !== 200) throw new Error(body.code + " (request " + requestId + ")");

  const item = body.item;
  if (item.status === "retired" && item.replaced_by) {
    // Retired items still resolve. Follow the pointer, and store the new ID so you stop asking about the old one.
    if (hops >= 3) throw new Error("Too many replacements in a row for " + ixId);
    return resolveItem(item.replaced_by, hops + 1);
  }
  return { show: item, store: item.ix_id, reason: item.status };
}

Watch for

  • Never parse an IX ID to work out its replacement. Only replaced_by says what replaces it.
  • IX IDs are permanent and never reused, so an ID you stored years ago is safe to look up again.

The calls are described in the API reference.