Skip to content

Connect Deel

Connect Deel so joiners, leavers, job and team changes, and pay changes for your employees and contractors reach Flowstate without anyone typing them in again. The forecast and budgets then work from the people you employ today.

You need access to integrations. Ask your Flowstate admin. First decide whether Deel is where people changes are made: see Get your people data into Flowstate.

How it connects

Flowstate works with Deel's API and webhooks. We recommend the event-driven route for Deel. Deel sends a webhook when a contract is created, amended or terminated, and when someone is terminated. It also allows only 5 API requests per second across every token in your organisation, and keeps pay on each contract in a different shape for contractors and for employees. Middleware can react to each change, pace its requests and run the periodic check against Deel that Deel itself advises.

RouteHow it worksChoose it when
Event-driven (recommended)Your middleware, such as Workato, Boomi, MuleSoft, Make or n8n, receives Deel's webhooks and updates Flowstate through the REST API.You run middleware, or can.
Scheduled syncA custom integration in Flowstate pulls from Deel's API on a schedule, from every 15 minutes to daily.You don't run middleware.

What you need from Deel

  • Someone with access to Deel's Developer Center (More → Developer).
  • An organisation API token, which covers your whole organisation. A personal token acts as one person.
  • Scopes on the token to read people, contracts, organisations (for departments) and, if you want openings as vacancies, hiring. For webhooks, also read and write webhooks.

Set it up

In Deel

  1. Go to More → Developer → Access Tokens and select Generate new token.
  2. Choose an organisation token and the scopes above.
  3. Copy the token. Deel recommends rotating tokens from time to time.

In Flowstate, for the event-driven route

  1. Go to Settings → Users & Access → API Keys and create a key that can view, create and update employees, contractors and vacancies.
  2. Your technical team subscribes your middleware to Deel's webhooks, in the Developer Center or through Deel's API. See For your technical team.
  3. Your technical team has the middleware update Flowstate. See Sync people from an HR system with the REST API.
  4. Your technical team schedules the middleware to compare everyone in Deel with Flowstate regularly, to catch any change a webhook didn't carry.

Your Flowstate contact helps your technical team with the mapping from Deel to Flowstate.

In Flowstate, for a scheduled sync

  1. Ask your Flowstate contact to switch on custom integrations for your organisation. They provide the hook for Deel and help your technical team configure it.
  2. Go to Settings → Integrations → Custom Integrations: select Browse catalog and open Custom Integrations.
  3. Select Create Integration. Enter a Name, such as Deel, and a Source System Key, such as deel. Select Create. You can't change the key later.
  4. Under Credentials, select Add Credential and store the Deel token, using the key name your Flowstate contact gives you.
  5. Under Hooks, select Create Hook. Choose Pull as the Hook Type and Employee as the Entity Type, then select Create. Add the hook's code and select Save Code. Add hooks for contractors and vacancies the same way.
  6. On the hook's Settings tab, turn on Run on schedule and choose an Interval. For Daily, choose a Preferred hour. Select Save Code.
  7. Select Test (Dry Run) and open Preview. Check that nobody already in Flowstate is about to be created a second time.
  8. Turn the hook on with the switch at the top of the editor, and confirm Enable Hook.

Each step in more detail: Manage a custom integration in Settings.

People already in Flowstate

If you loaded people by spreadsheet before connecting Deel, your technical team links each one to their Deel ID before the first sync. See Adopt people who are already in Flowstate.

What syncs

DeelFlowstate
Person IDExternal ID, which is how Flowstate recognises the person on every sync. One person can have several contracts in Deel.
First name, last name, work emailName and Email address
Job titleRole. A job title Flowstate hasn't seen before adds a job role.
DepartmentCurrent team. Deel also has teams; check with your Deel admin whether they match your Flowstate teams before using them.
Direct managerLine manager. Middleware can send it. A scheduled sync can't: set it in Flowstate.
Hiring type: contractor, employer of record, PEO or direct employeeContractors come in as contractors, with their rate. Everyone else comes in as an employee, with their salary.
FTE percentage, and full-time or part-timeFTE on their team
Start date, and completion or termination dateEmployment dates
Pay: a contractor's amount, currency and rate period; an employer-of-record employee's annual salary and currencyA contractor's rate, or an employee's salary changes on the Compensation tab. Agree with your Flowstate contact which date a pay change takes effect from.
Hiring openings: title, status, new hire or backfill, team, target start date and pay rangeVacancies
Country and work locationLocation. Middleware can send it. A scheduled sync can't: set it in Flowstate.
Not in DeelWork type (Employment type on the person's record), which sets their overhead. Set it in Flowstate, or send it from middleware.

To set location, work type or line manager in Flowstate, go to Resourcing → People and teams → People, open the person and change them under Employee details. Nothing goes back to Deel.

How changes arrive

  • When. With the event-driven route, as Deel sends each change, plus your middleware's regular check. With a scheduled sync, on the schedule you chose, from Every 15 minutes to Daily.
  • Edits made in Flowstate. Middleware updates only what changed in Deel, so an edit in Flowstate stays until Deel sends a change to the same detail, or the regular check puts Deel's value back. A scheduled sync sets everything it sends back to Deel's value on every run. Either way, make those changes in Deel. More in Edits made in Flowstate.
  • Leavers. When a contract or person is terminated in Deel, the person gets an end date in Flowstate. They stay in past months of the forecast and effort. Nothing deletes them.
  • Rehires. A returning person keeps their old end date in Flowstate until it's cleared. Your technical team clears it through the REST API. See Undo a leaver.
  • Future-dated pay. A pay change with a future effective date shows as Scheduled on the Compensation tab until that date.

Check it's working

  1. Event-driven: in your middleware, check that recent Deel events were received and that Flowstate accepted each update. Scheduled sync: open the hook, select Execution History, and find the latest run with Scheduled under Triggered By. It shows Completed, with a count under Records.
  2. Go to Resourcing → People and teams → People and compare a few people with Deel: a recent joiner, a recent leaver (Filter → Status → Include off-boarded) and someone with a recent pay change. Check Role, Current team, Employment dates and the Compensation tab.
  3. Open a person's Changes tab to see each change, who made it and when.

If something's not right

Changes from Deel stopped arriving. Deel switches a webhook off after 10 failed deliveries in a row. Fix what your middleware was returning, then turn the webhook back on in Deel.

Requests to Deel fail with rate-limit errors. Deel allows 5 requests per second for your whole organisation, shared with every other tool using a Deel token. Ask your technical team to slow the middleware or the hook.

Contractors show up as employees, or pay looks wrong. Deel keeps pay in a different form for each hiring type. Check the person's hiring type in Deel, and tell your Flowstate contact about any contract types that come in wrongly.

The token stopped working. It was deleted or rotated in Deel. Generate a new one and update it in your middleware, or update the credential for a scheduled sync.

For your technical team

API. https://api.letsdeel.com/rest. Sandbox: https://api-staging.letsdeel.com/rest, with separate credentials and the same rate limits. Choose a version with X-Version: YYYY-MM-DD. The /rest/v2/ prefix is legacy but still works; if you send both, the header wins.

Auth. Authorization: Bearer <token>. Scopes follow resource:read / resource:write: people:read, contracts:read, organizations:read, ats:read, and webhooks:read plus webhooks:write for webhooks. OAuth apps must also send x-client-id on every call; their access tokens last 30 days, and refresh tokens last 90 days and are single-use.

Endpoints.

  • GET /people pages by offset and limit (page{offset, total_rows, items_per_page}), with filters hiring_types, hiring_statuses, teams, search and fields. Returns id, first_name, last_name, work_email, job_title, department{id, name}, hiring_type, start_date, completion_date and employments[].
  • GET /people/{hris_profile_id} with include_worker_relations=true returns direct_manager and direct_reports[], plus country, state and work_location. include_custom_fields=true adds custom fields.
  • GET /contracts pages by cursor (after_cursor), with filters types, statuses, legal_entity_id, team_id and external_id.
  • GET /contracts/{id} returns compensation_details{amount, currency_code, scale, frequency}, fte_percentage, employment_type (FULL_TIME, PART_TIME), start_date and termination_date. expand=custom_fields adds custom fields.
  • GET /eor/contracts/{id}/details returns salary (annual, as a string), currency and work_hours_per_week (a string, such as "40.00").
  • GET /departments returns id, name and parent.
  • GET /ats/openings (cursor-paged) returns title, status, opening_type_slug, team, location, employment_type, target_start_date, min_compensation_amount, max_compensation_amount, compensation_currency_iso_code and compensation_period.

Gotchas.

  • hiring_type is contractor, eor, direct_employee, peo or hris_direct_employee. Pay lives on different endpoints in different shapes per type, so normalise per type. One person can hold several contracts over time.
  • Contract type: ongoing_time_based, milestones, time_based, pay_as_you_go_time_based, commission, payg_milestones, payg_tasks, eor, peo, employee, global_payroll, shield_msa, hris_direct_employee, contractor_outside_deel, unknown.
  • The contract status list is long (waiting_for_*_sign, in_progress, completed, cancelled and more). Decide which statuses count as current people.
  • Check the contract response for the date a pay change takes effect before choosing what to send as effectiveDate.
  • Map terminations to endDate in Flowstate. Don't delete the person.

Rate limits. 5 requests per second for the whole organisation, across all tokens, on a rolling 1-second window. There are no rate-limit headers, so queue requests 200 ms apart.

Webhooks, for middleware.

  • Subscribe with POST /webhooks (url, name, description, events[], status, api_version, optional signing_key, include_child_orgs), or in the Developer Center. GET /webhooks/events/types lists every event with a payload example: use it to confirm the people events you need.
  • Events include contract.created, contract.status.updated, contract.amended, contract.terminated and people.terminated.
  • Payload: data.meta.event_type, data.meta.organization_id, data.resource and timestamp.
  • Verify x-deel-signature: HMAC-SHA256 of "POST" followed by the raw body, keyed by the signing key. x-deel-hmac-label names the key and x-deel-webhook-version is also sent. Compare in constant time.
  • Respond within 30 seconds; Deel advises under 5. Deel retries 9 times with exponential backoff, from 1 minute to 4 hours, and switches the webhook off after 10 consecutive failures.
  • De-duplicate events and reconcile regularly, as Deel advises.

Deel docs.

Flowstate Documentation