Koppelingen
Eyetelligence is te koppelen aan externe applicaties, zoals bijvoorbeeld Sjapo. Dezelfde gegevens zijn zowel via onze API als via een MCP-server te benaderen. Beide gebruiken dezelfde API-key.
Informatie voor managers
Om te koppelen zul je een API-key moeten aanmaken en deze verstrekken aan de applicatie waarmee je koppelt (bijvoorbeeld Sjapo) zodat ze bij jouw gegevens kunnen. Neem contact met ons op zodat we jouw API-key kunnen verstrekken, dit kun je (nog) niet zelf doen. Dezelfde API-key werkt zowel voor de API als voor de MCP-server.
API
Voor specifiek maatwerk of concullega-applicaties bieden we een GraphQL API aan.
- We maken gebruik van GraphQL
- Het schema is beschikbaar op
https://cockpit.eyetelligence.nl/api/api/schema - Het endpoint is:
https://cockpit.eyetelligence.nl/api/api/query - De API-key moet als header meegegeven worden in de vorm:
Authorization: Bearer [mijn token] - Er geldt een fair-use policy
- Gebruik onderstaande query om de relevante data op te halen:
query ($period: Period!, $year: Int!) {
sjapo(period: $period) {
id
employee {
id
employeeNumber
name
givenNames
prefix
surname
email
dateOfBirth
address {
country
region
city
street
houseNumber
houseNumberAddition
postcode
}
}
startDate
endDate
hours(period: $period)
attendances(period: $period) {
id
startCorrected
}
overtimeHours(period: $period)
illnessHours(period: $period)
shifts(period: $period) {
id
start
end
comment
breakDuration
shiftType
}
availabilities(period: $period) {
id
start
end
isAvailable
comment
}
todos(period: $period) {
label
}
}
journals(year: $year) {
employeeName
employeeNumber
period
year
run
department
costCenter
costUnit
percentage
generalLedgerAccount
componentName
debit
credit
total
}
}
Bijvoorbeeld:
curl https://cockpit.eyetelligence.nl/api/api/query \
-H 'Authorization: Bearer apitoken' \
--data-urlencode 'query=
query ($period: Period!, $year: Int!) {
sjapo (period: $period) {
id
employee {
id
employeeNumber
name
givenNames
}
startDate
endDate
hours(period: $period)
shifts(period: $period) {
id
start
end
comment
shiftType
}
availabilities(period: $period) {
id
start
end
isAvailable
comment
}
todos(period: $period) {
label
}
}
journals(year: $year) {
employeeName
employeeNumber
period
year
run
department
costCenter
costUnit
percentage
generalLedgerAccount
componentName
debit
credit
total
}
}
' \
--data-urlencode 'variables={"period":{"year":2023,"period":7},"year":2024}'
Omzet
Gebruik de receiptItems-query om de verkochte regels over een datumbereik op
te halen: per regel het aantal, de prijzen, het btw-percentage en de categorie.
De omzetdag volgt de POS-instelling van het bedrijf, zodat dit overeenkomt met
de overige omzetrapportages. Optellen per dag, categorie of vestiging doe je
zelf.
query ($firm: FirmInputType!, $fromDate: Date!, $toDate: Date!) {
receiptItems(firm: $firm, fromDate: $fromDate, toDate: $toDate) {
id
name
quantity
createdAt
taxPercentage
totalTaxExclusivePrice
totalTaxInclusivePrice
category
categoryType
}
}
Bijvoorbeeld:
curl https://cockpit.eyetelligence.nl/api/api/query \
-H 'Authorization: Bearer apitoken' \
--data-urlencode 'query=
query ($firm: FirmInputType!, $fromDate: Date!, $toDate: Date!) {
receiptItems(firm: $firm, fromDate: $fromDate, toDate: $toDate) {
name
quantity
createdAt
totalTaxInclusivePrice
category
}
}
' \
--data-urlencode 'variables={"firm":{"id":1},"fromDate":"2024-01-01","toDate":"2024-01-31"}'
Diensten
Gebruik de shifts-query om de geplande diensten uit het gepubliceerde
rooster op te halen over een datumbereik. Per dienst krijg je start, eind,
pauze, duur, de ingeroosterde medewerker (of null bij een open dienst),
de track, gepubliceerd-status en de verwachte loonkosten. Filter optioneel
op shiftTypeIds en/of employeeId. Zet includeUnpublished op true
om ook eigen (nog niet gepubliceerde) wijzigingen terug te zien.
query (
$firm: FirmInputType!
$fromDate: Date!
$toDate: Date!
$includeUnpublished: Boolean = false
$shiftTypeIds: [ID]
$employeeId: ID
) {
shifts(
firm: $firm
fromDate: $fromDate
toDate: $toDate
includeUnpublished: $includeUnpublished
shiftTypeIds: $shiftTypeIds
employeeId: $employeeId
) {
id
start
end
breakDuration
durationHours
employeeId
employee {
id
employeeNumber
fullName
}
track
isPublished
expectedCost
}
}
Medewerkers
Gebruik de employees-query om de medewerkers van een vestiging op te halen,
gearchiveerde medewerkers niet meegerekend. Dit is de lijst waarmee je een
naam aan een id koppelt. isWorkReady zegt of iemand op de opgegeven datum
aan alle eisen voldoet om te mogen werken; ontbreekt er iets, dan staat in
notWorkReadyMessages wat. Voor externe medewerkers (isExternal) staat
isWorkReady altijd op true: die gegevens houdt de vestiging niet bij, dus
het betekent dat er niets is gecontroleerd en niet dat alles in orde is.
query ($firm: FirmInputType!, $atDate: Date) {
employees(firm: $firm, atDate: $atDate) {
id
employeeNumber
fullName
isExternal
isWorkReady
notWorkReadyMessages
}
}
Werkcodes
Gebruik de workCodes-query om de actieve werkcodes van een vestiging op te
halen. Deze codes categoriseren het soort werk op een dienst. Verwijderde codes
komen niet mee.
query ($firm: FirmInputType!) {
workCodes(firm: $firm) {
code
name
}
}
Factuurcodes
Gebruik de billingCodes-query om de actieve factuurcodes van een vestiging op
te halen. Deze codes zeggen aan wie een dienst wordt doorbelast. Verwijderde
codes komen niet mee.
query ($firm: FirmInputType!) {
billingCodes(firm: $firm) {
code
name
}
}
Gewerkte diensten
Gebruik de attendances-query om de daadwerkelijk gewerkte diensten op te
halen over een datumbereik. Alleen gereviewde diensten worden teruggegeven;
startCorrected en endCorrected zijn de gecorrigeerde (gereviewde) tijden.
Per dienst krijg je start, eind, pauze, netto gewerkte uren, het id van de
medewerker en de werkelijke loonkosten. Voor de definitieve cijfers — inclusief
de reservering van vakantie-uren — gebruik je de journals.
premiumHours geeft de toeslaguren per toeslagpercentage, zoals ook bij de
uren in de cockpit te zien is. Het percentage is een fractie: 0.5 betekent
50% toeslag. totalPremiumHours is het totaal aan toeslaguren.
query ($firm: FirmInputType!, $fromDate: Date!, $toDate: Date!) {
attendances(firm: $firm, fromDate: $fromDate, toDate: $toDate) {
id
startCorrected
endCorrected
breakDuration
durationHoursCorrected
employeeId
actualCost
totalPremiumHours
premiumHours {
percentage
totalHours
brackets {
bracketName
premiumHours
componentCode
ruleHumanReadable
}
}
}
}
Publiceerwaarschuwingen
Gebruik de warnings-query om te zien wat er misgaat als het conceptrooster
zou worden gepubliceerd. Dit is dezelfde controle die de planner bij het
publiceren te zien krijgt: werkregels, vakantie, ziekte en beschikbaarheid.
De waarschuwingen komen gegroepeerd per categorie, en per regel krijg je de
diensten die de regel raakt. Er wordt niets gepubliceerd en het
conceptrooster verandert niet. Laat je shiftTypeIds weg, dan tellen alle
diensttypes mee.
query ($firm: FirmInputType!, $publishUntil: Date!, $shiftTypeIds: [ID]) {
warnings(firm: $firm, publishUntil: $publishUntil, shiftTypeIds: $shiftTypeIds) {
name
rules {
label
shifts {
id
start
end
employeeId
}
}
}
}
Dienstconflicten
Gebruik de shiftConflicts-query voor overlap in het conceptrooster:
medewerkers die op hetzelfde moment voor twee diensten staan, binnen een
vestiging (employeeOverlap) of over vestigingen heen (crossFirmOverlap).
Elk conflict geeft de diensten die met elkaar botsen.
Geef je untilDate mee, dan wordt gesimuleerd wat er gebeurt als er tot en
met die datum wordt gepubliceerd, waarna de simulatie wordt teruggedraaid.
Ook hier wordt niets gepubliceerd.
query ($firm: FirmInputType!, $untilDate: Date, $shiftTypeIds: [ID]) {
shiftConflicts(firm: $firm, untilDate: $untilDate, shiftTypeIds: $shiftTypeIds) {
employeeOverlap {
label
shifts {
id
start
end
employeeId
}
}
crossFirmOverlap {
label
shifts {
id
start
end
employeeId
}
}
}
}
Beschikbaarheid
Gebruik de availabilities-query om over een datumbereik op te halen wanneer
de medewerkers van een vestiging wel en niet kunnen werken. Dit is dezelfde
beschikbaarheid die de planner ziet. Het bereik wordt opgeknipt in stukken:
per stuk zegt status hoe de tijd van de medewerker eruitziet, en comment
wat die erbij heeft geschreven.
status |
Betekenis |
|---|---|
ILLNESS |
ziek |
SCHEDULED |
al ingeroosterd |
HOLIDAY |
goedgekeurde vakantie |
NOT_AVAILABLE |
de medewerker heeft geantwoord dat die niet kan |
AVAILABLE |
de medewerker heeft geantwoord dat die kan |
REQUESTED |
gevraagd, nog geen antwoord |
NOT_REQUESTED |
er loopt geen beschikbaarheidsvraag |
Ziekte, vakantie en diensten tellen ook buiten een beschikbaarheidsvraag mee.
Valt er meer tegelijk, dan wint de bovenste: een dienst op een dag dat iemand
ziek is, heeft status ILLNESS. deadline is de uiterste datum waarop de
medewerker nog kon antwoorden.
De velden isAvailable en eventType bestaan nog, maar zijn verouderd en
verdwijnen in een volgende versie. Gebruik status.
query ($firm: FirmInputType!, $fromDate: Date!, $toDate: Date!) {
availabilities(firm: $firm, fromDate: $fromDate, toDate: $toDate) {
employeeId
start
end
comment
deadline
status
}
}
MCP
Dezelfde GraphQL API is ook beschikbaar via een MCP-server (Model Context Protocol), zodat AI-clients zoals Claude Code het schema kunnen ontdekken en zelf queries en mutaties kunnen uitvoeren.
- Het endpoint is:
https://cockpit.eyetelligence.nl/mcp - Het transport is streamable HTTP
- De API-key moet als header meegegeven worden in de vorm:
Authorization: Bearer [mijn token] - De koppeling scoping (welke firma) en rechten volgen automatisch uit de API-key, precies zoals bij de API
- De server ondersteunt introspectie, zoeken in het schema, en het uitvoeren van queries en mutaties
- Er geldt een fair-use policy
Configureer de server bijvoorbeeld in een .mcp.json voor Claude Code:
{
"mcpServers": {
"cockpit-eyetelligence": {
"type": "http",
"url": "https://cockpit.eyetelligence.nl/mcp",
"headers": { "Authorization": "Bearer apitoken" }
}
}
}