payfit
payfit.
The PayFit company the API key belongs to — name, country, registration
setup & usage
log in to PayFit as a company admin, then Integrations → API (app.payfit.com/integrations/hub/api) → "Create a key": give it an explicit label and tick read scopes only, then copy it — it is not shown again afterwards. paste it into your oto connector keys under payfit.
collaborators:read, collaborators:management:read, collaborators:contracts:read, collaborators:personal:read, collaborators:legal-identity:read, contracts:read, contracts:payslips:read, time:read, accounting:read, health-insurance:read, collaborators:meal-vouchers:readcollaborators:social-security:read (NIR), collaborators:bank-info:read (IBAN), payment-files:read (payment file)collaborators:write, collaborators:contracts:write, time:write, health-insurance:write): the connector does not use them. on an existing key that carries some, they are useless and can be removed on the PayFit sidea PayFit key opens only one company, and the API has no group view: two companies = two independent keys. create a key in each PayFit company, then set each one as a company of the connector (section "multiple companies").
_account would be the figure of a single company presented as the group'sstart with payfit_company(): its country says whether the French variants apply (FR contracts, meal vouchers, worked time, health insurance).
payfit_collaborator() (next page: cursor=<next_cursor>)payfit_contract(fr=True) (natureContratDsn: 01 CDI, 02 CDD…; workingTimeModality: forfait_jours…)payfit_absence(begin_date="YYYY-MM-DD", end_date="YYYY-MM-DD"), then link contractId to a collaborator's contractspayfit_payroll(op="accounting", date="202601"): one row per entry, with account, label, debit, credit, employee and analytic codes. this is the only structured numeric data in the API — payroll cost, charges and benefits in kind are read there by account number (641x, 645x, 6417x)payfit_payroll(date="202601") (op status by default) before using any figurespayfit_payroll(op="accounting_export", date="202601"); "the payment file" → op="payment_file" — documents locked by default, see the note on personal datapayfit_payslip(collaborator_id=…) for the list, then op="download" with the three identifiers of the row: the PDF text comes back readable, the original PDF as raw_url (locked by default, like any document)payfit_payslip(op="overtime", collaborator_id=…, date="202601"): only the overtime / complementary / increased-rate hours lines of the payslip, read server side (the payslip does not go out). the numbers are returned in the line's order, with no role assigned: check the reading against a payslip before totalling, and never add an allegement line (contribution reduction) to the paid amount. for a company, loop over payfit_collaborator()payfit_worked_time(date="202601") · "meal vouchers" → payfit_meal_voucher(date="202601")payfit_insurance() for the company's contracts, kind="provident" for provident cover202601), never 2026-01: it is the only form PayFit acceptsthe connector never writes to PayFit, whatever the argument. the write ops still exist in their tools, but each returns the named refusal payfit_write_not_wired, which says what the call would have done — nothing is sent:
payfit_collaborator(op="create"), payfit_contract(op="create")payfit_absence(op="create") and op="cancel"payfit_insurance(op="affiliate") and op="regularize"there is neither an org switch nor an activation by an administrator: the capability does not exist in the connector. a hire, a contract, an absence or an affiliation is done in PayFit itself.
these questions come up often and have no endpoint — oto will not fabricate them, and an invented answer would be wrong:
op="overtime" READS from the PDF. to get them as accounting data, isolate them on a dedicated sub-account in PayFit's accounting settings (the API cannot do it): the new account will appear as is in op="accounting"payfit_worked_time)payfit_document) are British; on a French company the list is empty, and that is the right answerthe connector no longer removes anything in a hard-coded way: it serves what the key allows, and protection is an org policy, editable.
absence_type) — sickness, work accident, maternity are health data. a •••• is a masked value, not missing dataabsence_category always stays readable: ordinary_leave (paid leave, RTT, rest, unpaid, remote work, school) or restricted for everything else — enough to plan a workload without reading a reasonoto_org_settings domain=field_filters op=set service=payfit rules=[] unmask=["iban"] (accepted names: those of the server default, under their output name). the org policy is added to the default: without unmask, nothing comes out in clear, and rules: [] alone is refused (floor_lift_must_be_explicit). the response lists the fields now in clear under unmasked. ⚠️ *clearing* the policy (rules: null) restores the server default as isoto_org_settings domain=field_filters op=set service=payfit rules=[] documents=true. this consent lifts no mask from the JSON responses. otherwise the call is refused, saying so, and the refusal is not a bug. if the policy cannot be read, the document is refused too. payfit_payslip(op="overtime") is not locked: it only returns the overtime lines, never the payslip. their numbers (numbers, rates) are filtered by the policy like any data; the raw line (line), a verbatim excerpt of the payslip, follows the documents lock (line_withheld says why otherwise)this connector accepts multiple sociétés: each stored credential becomes a named account (one name per société), at your level, your team's or your org's.
_account="<name>" on the tool; list them: oto_identity(op='list', connector='payfit') (scope='org' or scope='group' for the org's or team's)oto_identity(op='set', connector='payfit', identity_id='<name>'); rename: op='rename' with new_name_account) and adding upoutils
utilisation
claude plugin marketplace add otomata-tech/oto-plugin — mcp + skill configurés.pipx install oto-cli puis oto payfit …