Recopart integration guide
This is an end-to-end guide for a Recopart-style integration: a parts ERP that manages many dismantling yards and pushes inventory to Rheo for listing on Tradera. It uses the real, live API and the C# SDK.
1. Authentication
All item calls use your API key in the x-api-key header. The C# SDK sets it for you:
using Rheo.Sdk;using Rheo.Sdk.Types;
var rheo = new RheoClient(new RheoClientOptions{ ApiKey = Environment.GetEnvironmentVariable("RHEO_API_KEY")!, WebhookSecret = Environment.GetEnvironmentVariable("RHEO_WEBHOOK_SECRET"),});2. The real endpoints
| Method | Path | Purpose |
|---|---|---|
PUT | /integration/v1/items/{external_id} | Create or update an item (upsert by your id). |
GET | /integration/v1/items/{external_id} | Status (Rheo + Tradera). |
PATCH | /integration/v1/items/{external_id}/price | Update price. |
PATCH | /integration/v1/items/{external_id}/status | Set sold or not_listed. |
DELETE | /integration/v1/items/{external_id} | Remove (archived if an order is in progress). |
POST | /integration/v1/items/batch | Upsert up to 500 items. |
GET | /integration/v1/items | List/sync with filters + cursor pagination. |
GET | /integration/v1/items/{external_id}/children | Parts under a donor vehicle. |
GET | /integration/v1/items/{external_id}/summary | Roll-up across a vehicle’s parts. |
GET | /integration/v1/items/{external_id}/history | Lifecycle history for an item. |
3. Mapping a part — the domain shape
A part is an auto_parts item with the donor vehicle and part nested under domain.
Recopart’s PartCode goes in part.catalogCodes.recopart. Reserve oemNumber for
true OEM part numbers.
await rheo.Items.UpsertAsync("10-23215783", new UpsertItemRequest{ Title = "Stötdämpare bak — Volvo XC90 2018", Price = 950, ShippingCost = 149, ImageUrls = ["https://cdn.recopart.example/10/23215783/1.jpg"], Domain = new AutoPartsDomain { Vehicle = new DonorVehicle { Manufacturer = "Volvo", Model = "XC90", Year = 2018, VehicleType = "Bil", }, Part = new PartInfo { Name = "Stötdämpare bak", OemNumber = "31400452", // a real OEM number, if known CatalogCodes = new Dictionary<string, string> { ["recopart"] = "7118", // Recopart's internal PartCode }, }, ConditionGrade = "B", }, AutoPublishTradera = true,});Donor vehicle as a container (optional but recommended)
Model the donor vehicle as a container, then attach parts to it via ParentExternalId.
Containers are not sold themselves — they give you a per-vehicle roll-up
(SummaryAsync) and a parts list (ChildrenAsync).
await rheo.Items.UpsertAsync("10-VIN-YV1CZ714581234567", new UpsertItemRequest{ Type = RheoItemType.Container, Title = "Volvo XC90 II 2018 — donor", Metadata = new Dictionary<string, object?> { ["vin"] = "YV1CZ714581234567" },});
await rheo.Items.UpsertAsync("10-23215783", new UpsertItemRequest{ ParentExternalId = "10-VIN-YV1CZ714581234567", Title = "Stötdämpare bak", Price = 950, Domain = new AutoPartsDomain { /* … as above … */ },});4. Many yards, one key — reseller routing
Recopart is a reseller: one API key manages every yard, each of which is a Rheo
member account. Route each call to a yard with ForAccount,
passing the yard’s reference (its external_id, e.g. 10):
// Push to yard 10, then yard 22 — same client, same keyawait rheo.ForAccount("10").Items.UpsertAsync("10-23215783", part10);await rheo.ForAccount("22").Items.UpsertAsync("22-55012", part22);
// Reconcile a single yard's live inventoryvar liveAt10 = await rheo.ForAccount("10").Items.ListAsync( new ListItemsParams { Status = RheoItemStatus.Active });Yards onboard themselves through Recopart’s public page (rheo.se/p/recopart) — see
Onboarding. Recopart names each yard’s reference in the
Managed accounts UI; that name is what you pass to ForAccount. Each yard keeps its
own Tradera connection and payout; Rheo bills Recopart once for the whole network
(Deals & Billing).
5. Reacting to sales — webhooks
Register one webhook endpoint with scope: "members" to receive events from every
yard. Each delivery carries data.account.memberExternalId, so you decrement the right
yard’s stock:
app.MapPost("/webhooks/rheo", async (HttpRequest request, RheoClient rheo) =>{ using var reader = new StreamReader(request.Body); var rawBody = await reader.ReadToEndAsync(); var signature = request.Headers["X-Rheo-Signature"].ToString();
// Verify with the receiving endpoint's own secret RheoEvent evt; try { evt = rheo.Webhooks.Verify(rawBody, signature, endpointSecret); } catch (RheoWebhookSignatureException) { return Results.Unauthorized(); }
if (evt is ItemSoldEvent sold) { var yard = sold.Data.Account?.MemberExternalId; // e.g. "10" await recopart.DecrementStockAsync(yard, sold.Data.ExternalId, sold.Data.SalePrice); }
return Results.Ok();});Delivered events: item.created, item.images_ready, listing.created,
listing.ended, listing.failed, item.sold. Each endpoint has its own signing
secret — see Webhooks.
6. Recommended sync loop
- On dismantle, upsert the donor vehicle (container) and its parts (
ForAccount(yard)), mapping PartCode →catalogCodes.recopart. - Listen for
item.soldand decrement the originating yard’s stock. - Nightly, reconcile per yard with
ListAsync({ updatedSince })to catch anything missed.