Skip to content

Sales ​

Eén endpoint: elke sale die SalesDash heeft, met de agent en de propositie waarop hij geboekt is, in de volgorde waarin ze voor het laatst gewijzigd zijn. Het is gebouwd voor een periodieke poll — onthoud wanneer je voor het laatst vroeg, vraag daarna alles op wat sindsdien veranderd is, en je eigen kopie blijft actueel. Precies zoals de eigen providers van SalesDash lezen uit de systemen die zij pollen.

  • GET /sales geeft de sales, de nieuwste wijziging als laatste, vanaf een moment dat jij kiest.

Sales opvragen ​

GET /integrations/api/v1/sales?updated_from=2026-10-27T06:00:00Z&limit=500
ParameterVerplichtToelichting
updated_fromneeAlleen sales die op of na dit moment gewijzigd zijn. Laat weg voor de hele historie.
updated_toneeAlleen sales die op of vóór dit moment gewijzigd zijn.
cursorneeGa verder na een pagina — zie pagineren. De next-waarde van de vorige aanroep, ongewijzigd.
limitneeSales per aanroep, 1 tot 500. Standaard 100.

Beide grenzen zijn inclusief. Een moment schrijf je in UTC, op de seconde, met een Z: 2026-10-27T06:00:00Z. Elke tijd in een antwoord staat in hetzelfde formaat, dus een waarde die je ontving kan er zo weer in. Elke andere vorm wordt geweigerd.

json
{
  "sales": [
    {
      "id": 1,
      "external_id": "1784904509",
      "provider_id": 2,
      "sold_at": "2026-07-24T08:27:27Z",
      "cancelled_at": null,
      "is_retention": null,
      "contract_value_cents": 190100,
      "total_commission_cents": 0,
      "contact_key": null,
      "meta": {
        "connection_count": 2,
        "electricity_usage": 1300,
        "electricity_return": 100,
        "gas_usage": 0
      },
      "team_id": 1,
      "agent": {
        "id": 1,
        "name": "Olivia Stevens",
        "team_id": 1,
        "is_active": true
      },
      "proposition": {
        "id": 3,
        "name": "Omnis 3 jaar",
        "project_id": null,
        "is_active": true
      },
      "created_at": "2026-07-24T08:58:27Z",
      "updated_at": "2026-07-24T08:58:27Z",
      "deleted_at": null
    }
  ],
  "has_more": true,
  "next": "eyJ1IjoiMjAyNi0wNy0yNFQwODo1ODoyN1oiLCJpIjoxfQ"
}
VeldBetekenis
idHet eigen id van SalesDash voor de sale. Blijft het hele leven van de sale gelijk — sleutel je kopie hierop.
external_idHet id dat de sale heeft in het systeem waar hij vandaan komt, als hij van een provider komt.
provider_idDe provider die hem aanleverde, of null voor een handmatig ingevoerde sale.
sold_atWanneer de sale verkocht is. null voor een sale die (nog) niet als verkocht telt.
cancelled_atWanneer de sale geannuleerd is, of null.
is_retentiontrue voor een retentiesale, false voor een nieuwe, null als de bron het niet zei.
contract_value_centsDe contractwaarde, in centen — 190100 is €1.901,00.
total_commission_centsDe commissie die SalesDash voor deze sale berekende uit je commissieregels, in centen. 0 als er geen regel van toepassing is.
contact_keyDe sleutel die deze sale koppelt aan het contact waarmee hij gemaakt is, zoals de provider hem aanleverde.
agent_id, proposition_idDe ids achter de blokken agent en proposition hieronder. Ze staan er ook los bij omdat een blok null is voor een sale die nooit gekoppeld is én voor een sale waarvan de agent of propositie inmiddels verwijderd is — het id is wat je dan nog vertelt welke het was.
metaAlles wat de provider bij de sale opsloeg — energieverbruik, productregels, een telecombundel. De vorm hangt af van het propositietype en van de provider, dus lees het als een los object. Een leeg object is {}.
team_idHet team waar deze sale voor telt: het team van de agent op het moment van boeken, dat niet verandert als de agent later van team wisselt.
agentDe agent aan wie de sale is toegekend, of null voor een sale die niet aan een agent gekoppeld is — een provider levert eerst de sale, en de koppeling aan een agent kan later volgen.
propositionDe propositie waarop de sale gemaakt is, of null als hij daar nog niet aan gekoppeld is.
created_at, updated_atWanneer SalesDash de sale voor het eerst opsloeg, en wanneer hij voor het laatst gewijzigd is.
deleted_atnull voor een actieve sale. Gevuld als de sale verwijderd is — zie hieronder.

Elk moment is UTC met een Z. sold_at is het moment dat de provider doorgaf, updated_at is de eigen klok van SalesDash.

De blokken agent en proposition worden bij elke aanroep vers gelezen, maar een wijziging aan die — een hernoemde agent, een uitgezette propositie — is geen wijziging aan de sale, en brengt de sale dus niet terug in je volgende poll. Zie die blokken als gemak, en de ids als de feiten.

Verwijderde sales staan erin — als iemand ze in SalesDash verwijderde ​

Een sale die een admin in SalesDash verwijdert, blijft in de lijst staan, met deleted_at gevuld, en het verwijderen telt als wijziging: de sale komt vooraan in je volgende poll. Komt een sale terug met deleted_at, verwijder dan je kopie.

Een sale die de bron intrekt, verdwijnt helemaal

Trekt het systeem dat een provider pollt een sale in — een deal verwijderd in het CRM, een order geannuleerd bij de bron — dan haalt de processor hem volledig uit SalesDash, en is er geen rij meer die deze lijst kan tonen. Je kopie van zo'n sale krijgt geen deleted_at; hij komt gewoon niet meer terug. Als dat uitmaakt voor wat je bouwt, stem dan af en toe af: vraag een periode op zonder updated_from, en gooi elk id weg dat je hebt en dat er niet meer in zit.

Pagineren ​

Een aanroep geeft hooguit limit sales terug. Zijn er meer, dan is has_more true en is next de plek waar de lijst verdergaat: geef het mee als cursor in de volgende aanroep, met dezelfde updated_from, updated_to en limit als daarvoor, en herhaal tot has_more false is.

next is een ondoorzichtig token dat de laatste sale markeert die je ontving; de volgende aanroep gaat strikt daarna verder. Bouw of lees het niet zelf. Een sale die opnieuw wijzigt terwijl je aan het pagineren bent, komt later nog een keer langs, met zijn nieuwe updated_at.

Een kopie actueel houden ​

Het patroon dat de eigen providers van SalesDash gebruiken, en het patroon om over te nemen:

  1. Eerste run: roep aan zonder updated_from en volg next tot has_more false is. Sla elke sale op onder zijn id.
  2. Vóór elke volgende run noteer je de huidige tijd in UTC. Roep aan met updated_from op de tijd die je aan het begin van de vorige run noteerde, min ruim een uur, en volg next tot het einde.
  3. Voor elke sale die terugkomt werk je je kopie bij op id — of je verwijdert hem als deleted_at gevuld is.

De overlap is er omdat een sale een ogenblik ná het moment waarop de klok zei dat de poll begon in de database geschreven kan worden. De sales die je al had komen nog een keer langs en worden met dezelfde waarden opnieuw weggeschreven; dat is goedkoop, en veel goedkoper dan een sale die je nooit ziet. Een uur in plaats van een paar minuten, vanwege één nacht per jaar: als in oktober de klok teruggaat, herhaalt de eigen klok van SalesDash het uur van 02:00 tot 03:00, en een sale die in de tweede ronde van dat uur wijzigt, sorteert vóór een sale uit de eerste ronde. Een overlap die langer is dan dat uur is wat garandeert dat je hem toch ziet; een kortere zou hem missen zodra je pollinterval een uur of meer is. Sales die in dat uur wijzigen kunnen ook een updated_at tonen die een uur afwijkt van het echte moment — één keer per jaar, en alleen in dat uur.

Gebruik de updated_at van de laatste sale niet als start van de volgende run

Het is verleidelijk, en het werkt meestal. Het gaat mis als een sale wordt opgeslagen met een updated_at die een seconde of twee eerder ligt dan de laatste die je ontving — dat gebeurt zodra twee dingen tegelijk sales schrijven, en binnen precies de seconde waarin je laatste pagina eindigde. Verankeren op het moment waarop je eigen run begon, met de overlap hierboven, is daar immuun voor.

Als er iets misgaat ​

AntwoordWanneer
422 op updated_from of updated_toGeen UTC-moment in het formaat 2026-10-27T06:00:00Z.
422 op updated_toEerder dan updated_from, of voorbij het jaar 9999 — laat updated_to weg als je geen bovengrens wilt.
422 op cursorGeen waarde die dit endpoint als next teruggaf — meestal een token dat onderweg een teken kwijtraakte.
422 op limitGeen heel getal van 1 tot 500.

Zie het overzicht voor de 401- en 5xx-antwoorden die elk endpoint deelt.