{
  "info": {
    "name": "Trustburn API v1",
    "description": "Trustburn Public API v1.\n\nSet the collection variables first:\n\n- `baseUrl` - https://trustburn.com/api/v1 (already filled in)\n- `apiKey` - your key from https://trustburn.com/business/api\n\nEvery request inherits Bearer auth from the collection, so you only set the key once.\n\nDocs: https://trustburn.com/developers\nSpec: https://trustburn.com/developers/openapi.yaml",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      { "key": "token", "value": "{{apiKey}}", "type": "string" }
    ]
  },
  "variable": [
    { "key": "baseUrl", "value": "https://trustburn.com/api/v1", "type": "string" },
    { "key": "apiKey", "value": "tb_live_replace_me", "type": "string" },
    { "key": "companyId", "value": "6", "type": "string" },
    { "key": "listingId", "value": "0", "type": "string" },
    { "key": "transferId", "value": "0", "type": "string" }
  ],
  "item": [
    {
      "name": "Account",
      "item": [
        {
          "name": "GET /me",
          "request": {
            "method": "GET",
            "header": [],
            "url": { "raw": "{{baseUrl}}/me", "host": ["{{baseUrl}}"], "path": ["me"] },
            "description": "Confirms the key is live and reports scopes, limits and today's usage. The cheapest health check."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Reference data",
      "item": [
        {
          "name": "GET /categories",
          "request": {
            "method": "GET",
            "header": [],
            "url": { "raw": "{{baseUrl}}/categories", "host": ["{{baseUrl}}"], "path": ["categories"] },
            "description": "Closed category taxonomy. Use `slug` in a listing's `categories`."
          },
          "response": []
        },
        {
          "name": "GET /geo/countries",
          "request": {
            "method": "GET",
            "header": [],
            "url": { "raw": "{{baseUrl}}/geo/countries", "host": ["{{baseUrl}}"], "path": ["geo", "countries"] }
          },
          "response": []
        },
        {
          "name": "GET /geo/states",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/geo/states?country=US",
              "host": ["{{baseUrl}}"],
              "path": ["geo", "states"],
              "query": [{ "key": "country", "value": "US" }]
            }
          },
          "response": []
        },
        {
          "name": "GET /geo/cities",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/geo/cities?country=US&state=1407&q=den",
              "host": ["{{baseUrl}}"],
              "path": ["geo", "cities"],
              "query": [
                { "key": "country", "value": "US" },
                { "key": "state", "value": "1407", "description": "state id from /geo/states" },
                { "key": "q", "value": "den", "description": "name prefix, optional" }
              ]
            },
            "description": "Cities with population over 10000 - the same list the business cabinet offers."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Listings",
      "item": [
        {
          "name": "GET /listings",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/listings?page=1&per_page=50",
              "host": ["{{baseUrl}}"],
              "path": ["listings"],
              "query": [
                { "key": "page", "value": "1" },
                { "key": "per_page", "value": "50", "description": "1..100" }
              ]
            }
          },
          "response": []
        },
        {
          "name": "POST /listings (dry run)",
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Northwind Locks\",\n  \"website\": \"https://northwindlocks.com\",\n  \"phone\": \"+1 415 555 0134\",\n  \"email\": \"hello@northwindlocks.com\",\n  \"country\": \"US\",\n  \"dry_run\": true\n}",
              "options": { "raw": { "language": "json" } }
            },
            "url": { "raw": "{{baseUrl}}/listings", "host": ["{{baseUrl}}"], "path": ["listings"] },
            "description": "Runs every check and echoes the normalized fields without writing anything. Spends no daily quota."
          },
          "response": []
        },
        {
          "name": "POST /listings (create)",
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Northwind Locks\",\n  \"website\": \"https://northwindlocks.com\",\n  \"phone\": \"+1 415 555 0134\",\n  \"email\": \"hello@northwindlocks.com\",\n  \"country\": \"US\",\n  \"state_id\": 1416,\n  \"city\": \"San Francisco\",\n  \"address\": \"1 Market St, San Francisco, CA\",\n  \"description\": \"24/7 residential and commercial locksmith.\",\n  \"categories\": [\"security-and-investigations\"],\n  \"logo_url\": \"https://northwindlocks.com/logo.png\",\n  \"photos\": [\"https://northwindlocks.com/img/van.jpg\"]\n}",
              "options": { "raw": { "language": "json" } }
            },
            "url": { "raw": "{{baseUrl}}/listings", "host": ["{{baseUrl}}"], "path": ["listings"] },
            "description": "201 on success. Idempotent by domain: a repeat returns the existing card with \"existing\": true instead of creating a second one."
          },
          "response": []
        },
        {
          "name": "GET /listings/{id}",
          "request": {
            "method": "GET",
            "header": [],
            "url": { "raw": "{{baseUrl}}/listings/{{listingId}}", "host": ["{{baseUrl}}"], "path": ["listings", "{{listingId}}"] }
          },
          "response": []
        },
        {
          "name": "PATCH /listings/{id}",
          "request": {
            "method": "PATCH",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"description\": \"24/7 residential and commercial locksmith, licensed in California.\",\n  \"categories\": [\"security-and-investigations\"]\n}",
              "options": { "raw": { "language": "json" } }
            },
            "url": { "raw": "{{baseUrl}}/listings/{{listingId}}", "host": ["{{baseUrl}}"], "path": ["listings", "{{listingId}}"] },
            "description": "Partial update. `website` cannot be changed."
          },
          "response": []
        },
        {
          "name": "POST /listings/{id}/logo (by URL)",
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"url\": \"https://northwindlocks.com/logo.png\"\n}",
              "options": { "raw": { "language": "json" } }
            },
            "url": { "raw": "{{baseUrl}}/listings/{{listingId}}/logo", "host": ["{{baseUrl}}"], "path": ["listings", "{{listingId}}", "logo"] }
          },
          "response": []
        },
        {
          "name": "POST /listings/{id}/logo (file upload)",
          "request": {
            "method": "POST",
            "header": [],
            "body": {
              "mode": "formdata",
              "formdata": [{ "key": "file", "type": "file", "src": [] }]
            },
            "url": { "raw": "{{baseUrl}}/listings/{{listingId}}/logo", "host": ["{{baseUrl}}"], "path": ["listings", "{{listingId}}", "logo"] },
            "description": "Pick a local image file for the `file` field before sending."
          },
          "response": []
        },
        {
          "name": "POST /listings/{id}/photos",
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"urls\": [\n    \"https://northwindlocks.com/img/van.jpg\",\n    \"https://northwindlocks.com/img/team.jpg\"\n  ]\n}",
              "options": { "raw": { "language": "json" } }
            },
            "url": { "raw": "{{baseUrl}}/listings/{{listingId}}/photos", "host": ["{{baseUrl}}"], "path": ["listings", "{{listingId}}", "photos"] },
            "description": "Up to 10 URLs per call, 12 owner photos in the gallery in total. Rejected URLs come back in `photos_rejected`."
          },
          "response": []
        },
        {
          "name": "DELETE /listings/{id}/photos/{photoId}",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/listings/{{listingId}}/photos/0",
              "host": ["{{baseUrl}}"],
              "path": ["listings", "{{listingId}}", "photos", "0"]
            },
            "description": "Photo id comes from the listing card's photos[].id."
          },
          "response": []
        },
        {
          "name": "GET /listings/{id}/reviews",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/listings/{{listingId}}/reviews?page=1&per_page=20",
              "host": ["{{baseUrl}}"],
              "path": ["listings", "{{listingId}}", "reviews"],
              "query": [
                { "key": "page", "value": "1" },
                { "key": "per_page", "value": "20", "description": "1..100" }
              ]
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "Review transfers",
      "description": "Move reviews a business already collected on another platform onto its Trustburn profile, at its request.\n\nTwo steps: open a transfer (preview), then confirm it. Nothing reaches the profile before the confirm, and DELETE takes it all back within 30 days.\n\nTransferred reviews count towards the rating and the review counter; each carries a badge linking to `source_url`, which is mandatory and must be the company's profile on the source platform.\n\nThree ways in: `rows` as JSON, a `file` as multipart, or `mode: \"url\"` - which asks us to read the company's public profile page on the source platform. Rows and files answer 201 with a transfer already in `preview`; a URL answers 202 with an empty one you poll. `GET /reviews/transfers/sources` says which platforms can be fetched (`url_mode`) and why the rest cannot (`reason`).\n\nLimits: 5,000 rows / 10 MB per transfer (1,000 reviews per URL fetch). No cap on the number of transfers; re-sent reviews are dropped as duplicates. Does not spend a `listings_per_day` unit.\n\nSet `listingId` to one of your listings and `transferId` to the id the create call returns.",
      "item": [
        {
          "name": "GET /reviews/transfers/sources",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/reviews/transfers/sources",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "reviews",
                "transfers",
                "sources"
              ]
            },
            "description": "The closed list of source platforms. `code` is what you send as `source`; `label` is the word that appears in the badge on every transferred review."
          },
          "response": []
        },
        {
          "name": "GET /reviews/transfers/template.csv",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/reviews/transfers/template.csv",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "reviews",
                "transfers",
                "template.csv"
              ]
            },
            "description": "Our CSV template, as text/csv. Use it when the export you have is not a recognised Trustpilot / G2 / Capterra one - which is how Google reviews get here, since we do not fetch them."
          },
          "response": []
        },
        {
          "name": "GET /listings/{id}/reviews/transfers",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/listings/{{listingId}}/reviews/transfers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "listings",
                "{{listingId}}",
                "reviews",
                "transfers"
              ]
            },
            "description": "This listing's transfer history from every channel, newest first, plus how many of today's three slots are left and how many transferred reviews are live on the profile."
          },
          "response": []
        },
        {
          "name": "POST /listings/{id}/reviews/transfers (rows)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"source\": \"clutch\",\n  \"source_url\": \"https://clutch.co/profile/northwind-locks\",\n  \"rows\": [\n    {\n      \"author_name\": \"Jane Cooper\",\n      \"rating\": \"5\",\n      \"date\": \"2025-03-14\",\n      \"title\": \"Delivered exactly what they promised\",\n      \"text\": \"We hired them for a six-month rebuild and they shipped on time. Communication was clear every week.\",\n      \"review_url\": \"https://clutch.co/profile/northwind-locks#review-12345\",\n      \"source_review_id\": \"12345\"\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/listings/{{listingId}}/reviews/transfers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "listings",
                "{{listingId}}",
                "reviews",
                "transfers"
              ]
            },
            "description": "Opens a transfer in `preview` and returns the counters plus, row by row, everything that will not be imported and why. Writes nothing to the profile yet.\n\nRows we drop: rating outside 1-5 after normalisation (9/10 becomes 5), body under 20 characters, no usable date, a date in the future or over 10 years old, contact details or links in the body, and duplicates - inside the request and against everything previously transferred for this company."
          },
          "response": []
        },
        {
          "name": "POST /listings/{id}/reviews/transfers (fetch by URL)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"source\": \"techbehemoths\",\n  \"source_url\": \"https://techbehemoths.com/company/northwind-locks\",\n  \"mode\": \"url\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/listings/{{listingId}}/reviews/transfers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "listings",
                "{{listingId}}",
                "reviews",
                "transfers"
              ]
            },
            "description": "Give us the link instead of the reviews: we read that public profile page ourselves (our own user agent, one request per second, no headless browser) and turn it into the same preview an upload would produce.\n\nAnswers **202**, not 201, and the difference matters - the transfer exists but is EMPTY. Nothing has been fetched yet. Poll `GET /listings/{id}/reviews/transfers/{tid}` every few seconds (it normally takes 10-60s) until `status` leaves `uploaded`/`parsing`:\n\n- `preview` - items and counters are there, confirm as usual;\n- `failed` - read `error`, it is written for a person. A failed fetch does not spend one of the three daily slots.\n\nRead `fetch_note` and show it: it says what the fetch could NOT see (e.g. a profile advertising 18 reviews whose page only publishes 12).\n\nOnly platforms whose `url_mode` is true accept this - run `GET /reviews/transfers/sources` first. `source_url` must be a profile page on the platform named in `source`; a host that does not match is a 422. Cap: 1,000 reviews per fetch."
          },
          "response": []
        },
        {
          "name": "POST /listings/{id}/reviews/transfers (file)",
          "request": {
            "method": "POST",
            "header": [],
            "body": {
              "mode": "formdata",
              "formdata": [
                {
                  "key": "source",
                  "value": "trustpilot",
                  "type": "text"
                },
                {
                  "key": "source_url",
                  "value": "https://www.trustpilot.com/review/northwindlocks.com",
                  "type": "text"
                },
                {
                  "key": "file",
                  "type": "file",
                  "src": []
                }
              ]
            },
            "url": {
              "raw": "{{baseUrl}}/listings/{{listingId}}/reviews/transfers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "listings",
                "{{listingId}}",
                "reviews",
                "transfers"
              ]
            },
            "description": "The same endpoint with a CSV or JSON export. Pick a local file for the `file` field before sending.\n\nTrustpilot, G2 and Capterra exports are recognised by their header row, and so is our own template. Headers we do not recognise answer 422 `unknown_format` with the file's real headers - send them back as a `mapping` form field."
          },
          "response": []
        },
        {
          "name": "GET /listings/{id}/reviews/transfers/{tid}",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/listings/{{listingId}}/reviews/transfers/{{transferId}}?limit=50",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "listings",
                "{{listingId}}",
                "reviews",
                "transfers",
                "{{transferId}}"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "50"
                }
              ]
            },
            "description": "The transfer plus a page of the parsed rows, every status - the preview table. `limit` up to 200."
          },
          "response": []
        },
        {
          "name": "POST /listings/{id}/reviews/transfers/{tid}/confirm",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/listings/{{listingId}}/reviews/transfers/{{transferId}}/confirm",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "listings",
                "{{listingId}}",
                "reviews",
                "transfers",
                "{{transferId}}",
                "confirm"
              ]
            },
            "description": "Writes every pending row into the live review index and returns the recomputed rating. Only a transfer in `preview` can be confirmed; a second call answers 409.\n\nBy sending this you state that the business authorised the transfer and that these are genuine customer reviews of it.\n\nSynchronous: a 5,000-row transfer takes about half a minute. Raise the Postman timeout to 180s before trying a big one."
          },
          "response": []
        },
        {
          "name": "DELETE /listings/{id}/reviews/transfers/{tid}",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/listings/{{listingId}}/reviews/transfers/{{transferId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "listings",
                "{{listingId}}",
                "reviews",
                "transfers",
                "{{transferId}}"
              ]
            },
            "description": "Withdraws a completed transfer: the reviews leave the profile and the rating is recomputed. Self-service for 30 days after the import."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Companies & reviews",
      "item": [
        {
          "name": "GET /companies?domain=",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/companies?domain=semalt.com",
              "host": ["{{baseUrl}}"],
              "path": ["companies"],
              "query": [{ "key": "domain", "value": "semalt.com" }]
            },
            "description": "Full public card of the active company on that domain. Cacheable: keep the ETag and send it back as If-None-Match - a 304 spends no read quota."
          },
          "response": []
        },
        {
          "name": "POST /companies/lookup",
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"domains\": [\n    \"semalt.com\",\n    \"example-not-here-xyz.com\"\n  ]\n}",
              "options": { "raw": { "language": "json" } }
            },
            "url": { "raw": "{{baseUrl}}/companies/lookup", "host": ["{{baseUrl}}"], "path": ["companies", "lookup"] },
            "description": "Up to 100 domains, one unit of daily read quota for the whole call. Returns the compact card; the response mirrors the request order, with company: null where nothing was found."
          },
          "response": []
        },
        {
          "name": "GET /companies/{id}",
          "request": {
            "method": "GET",
            "header": [],
            "url": { "raw": "{{baseUrl}}/companies/{{companyId}}", "host": ["{{baseUrl}}"], "path": ["companies", "{{companyId}}"] }
          },
          "response": []
        },
        {
          "name": "GET /companies/{id}/reviews",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/companies/{{companyId}}/reviews?page=1&per_page=20&sort=newest",
              "host": ["{{baseUrl}}"],
              "path": ["companies", "{{companyId}}", "reviews"],
              "query": [
                { "key": "page", "value": "1" },
                { "key": "per_page", "value": "20", "description": "1..50" },
                { "key": "sort", "value": "newest", "description": "newest | oldest | highest | lowest" },
                { "key": "min_rating", "value": "1", "disabled": true },
                { "key": "max_rating", "value": "5", "disabled": true }
              ]
            },
            "description": "page * per_page must not exceed 10000; narrow with min_rating/max_rating instead of paging deeper."
          },
          "response": []
        },
        {
          "name": "GET /companies/{id}/stats",
          "request": {
            "method": "GET",
            "header": [],
            "url": { "raw": "{{baseUrl}}/companies/{{companyId}}/stats", "host": ["{{baseUrl}}"], "path": ["companies", "{{companyId}}", "stats"] },
            "description": "Rating, star distribution, 12-month series and the newest review's timestamp - one call instead of paging the whole review body."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Agency",
      "description": "Agency listing-years: buy a package, spend one unit per listing for a dofollow link and the Verified badge for a year. See https://trustburn.com/developers#agency",
      "item": [
        {
          "name": "GET /agency/balance",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/agency/balance",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "agency",
                "balance"
              ]
            },
            "description": "Listing-years left, listing-years spent, every package bought, and the live price ladder."
          },
          "response": []
        },
        {
          "name": "POST /agency/checkout",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"units\": 25\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/agency/checkout",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "agency",
                "checkout"
              ]
            },
            "description": "Creates a Stripe Checkout Session and returns its URL. Minimum 25 units. Nothing is charged and nothing is credited until Stripe confirms the payment."
          },
          "response": []
        },
        {
          "name": "POST /listings/{id}/upgrade",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/listings/{{listingId}}/upgrade",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "listings",
                "{{listingId}}",
                "upgrade"
              ]
            },
            "description": "Spends one listing-year on this listing: dofollow link and Verified badge for a year. No body. Call it again to renew. An empty balance answers 402 no_agency_credits with the price ladder."
          },
          "response": []
        }
      ]
    }
  ]
}
