Prerequisites

Overview

Before creating a new employment, you need to first define the employment requirements. This guide walks you through the necessary prerequisites, including checking country availability, gathering basic employee information, and understanding key validation rules.

Before you begin, ensure that:

Check country availability

The first prerequisite is to confirm that the country you are hiring in is supported by Remote. You can do this by calling the list countries endpoint. The API response of this call will include a list of all supported countries along with their respective country codes. These codes are required to create an employment. Refer to this guide to learn more about how to use this endpoint.

ℹ️ If your desired country is not on the list of supported countries, you can reach out to your Remote contact or email us at [email protected] to express your interest in hiring in that country.

Populate basic employment information

Next up, you need to populate the employment with employee's basic information. The Remote API requires this information for every supported country. As the required payload may vary by country, you will have to look up the exact payload using the JSON schema explained below.

Using JSON schema for expected payload

The Remote API uses JSON schemas to define the expected basic information payload format. You can retrieve the employment_basic_information JSON schema for your country using the show form schema endpoint. This endpoint requires two parameters: country_code and form. Let's say your country of employment is Canada, then your request will look like:

$ curl --location \
       --header 'Authorization: Bearer eyJraWQiO...' \
       --request GET 'https://gateway.remote-sandbox.com/v1/countries/CAN/employment_basic_information'

This will result in a detailed JSON schema providing the required fields, labels, description, and validation rules of hiring an EOR employee in that country.

{
  "data": {
    "additionalProperties": false,
    "allOf": [
      {
        "else": {
          "properties": {
            "seniority_date": false
          }
        },
        "if": {
          "properties": {
            "has_seniority_date": {
              "const": "yes"
            }
          },
          "required": [
            "has_seniority_date"
          ]
        },
        "then": {
          "required": [
            "seniority_date"
          ]
        }
      }
    ],
    "properties": {
      "department": {
        "properties": {
          "id": {
            "description": "(Optional) Select a department or create one.",
            "oneOf": [
              {
                "const": null
              }
            ],
            "title": "Department",
            "type": [
              "string",
              "null"
            ],
            "x-jsf-presentation": {
              "creatableOn": "name",
              "inputType": "select",
              "meta": "departments",
              "placeholder": "Search or create a department..."
            }
          },
          "name": {
            "description": "Name of the department to be created if none is selected",
            "maxLength": 255,
            "title": "Department name",
            "type": [
              "string",
              "null"
            ],
            "x-jsf-presentation": {
              "inputType": "text"
            }
          }
        },
        "title": "Department",
        "type": [
          "object",
          "null"
        ],
        "x-jsf-order": [
          "id",
          "name"
        ],
        "x-jsf-presentation": {
          "inputType": "fieldset"
        }
      },
      "email": {
        "description": "This is how the employee will access their account.",
        "format": "email",
        "maxLength": 255,
        "title": "Personal email",
        "type": "string",
        "x-jsf-presentation": {
          "inputType": "email"
        }
      },
      "has_seniority_date": {
        "description": "If the employee started working for your company before being added to Remote, then select Yes.",
        "oneOf": [
          {
            "const": "yes",
            "title": "Yes"
          },
          {
            "const": "no",
            "title": "No"
          }
        ],
        "title": "Does the employee have a seniority date?",
        "type": "string",
        "x-jsf-presentation": {
          "direction": "row",
          "inputType": "radio"
        }
      },
      "job_title": {
        "description": "We can hire most roles but there are some we cannot support. This includes licensed roles, blue collar workers, and employees with certain C-level job titles.",
        "maxLength": 255,
        "pattern": "\\S",
        "title": "Job title",
        "type": "string",
        "x-jsf-presentation": {
          "inputType": "text"
        }
      },
      "manager": {
        "properties": {
          "id": {
            "description": "(Optional) The person who will manage this employee day-to-day on the Remote platform.",
            "oneOf": [
              {
                "const": "48359c5f-ff4e-4a2c-83e9-5c6f6f22f8bb",
                "title": "Easha Abid",
                "x-jsf-presentation": {
                  "meta": {
                    "assigned_roles": [
                      {
                        "data_scope": "all",
                        "name": "Owner",
                        "slug": "6541dadb-d3e0-45a0-9e32-094df0e5ce95",
                        "type": "owner"
                      }
                    ]
                  }
                }
              },
              {
                "const": null
              }
            ],
            "title": "Manager",
            "type": [
              "string",
              "null"
            ],
            "x-jsf-presentation": {
              "inputType": "select",
              "meta": "team_members",
              "placeholder": "Select a manager"
            }
          }
        },
        "title": "Manager",
        "type": [
          "object",
          "null"
        ],
        "x-jsf-order": [
          "id"
        ],
        "x-jsf-presentation": {
          "inputType": "fieldset"
        }
      },
      "name": {
        "description": "Full employee name as it appears on identification document.",
        "maxLength": 255,
        "pattern": "\\S",
        "title": "Full name",
        "type": "string",
        "x-jsf-presentation": {
          "inputType": "text"
        }
      },
      "provisional_start_date": {
        "description": "The minimum onboarding time for Canada is 2 working days. We will confirm the start date once you invite the employee to do the self-enrollment. We strongly recommend a later start date if you plan to conduct background checks and want to lower termination risks and costs due to unsatisfactory results.",
        "format": "date",
        "maxLength": 255,
        "title": "Provisional start date",
        "type": "string",
        "x-jsf-logic-validations": [
          "blocked_date_validation"
        ],
        "x-jsf-presentation": {
          "blockedDates": [],
          "inputType": "date",
          "meta": {
            "mot": 2
          },
          "minDate": "2025-03-12",
          "softBlockedDates": []
        }
      },
      "seniority_date": {
        "description": "Please indicate if different from contract start date",
        "format": "date",
        "title": "Seniority date",
        "type": [
          "string",
          "null"
        ],
        "x-jsf-presentation": {
          "inputType": "date"
        }
      },
      "work_email": {
        "description": "The employee's company email. For example, [email protected].",
        "format": "email",
        "maxLength": 255,
        "title": "Work email",
        "type": "string",
        "x-jsf-presentation": {
          "inputType": "email"
        }
      }
    },
    "required": [
      "name",
      "email",
      "job_title",
      "provisional_start_date",
      "has_seniority_date"
    ],
    "type": "object",
    "x-jsf-logic": {
      "validations": {
        "blocked_date_validation": {
          "errorMessage": "Date is blocked due to the holiday season, and the limited availability of internal/external providers to process onboarding, payroll and benefits enrollments",
          "rule": {
            "!": {
              "in": [
                {
                  "var": "provisional_start_date"
                },
                []
              ]
            }
          }
        }
      }
    },
    "x-jsf-order": [
      "name",
      "email",
      "work_email",
      "job_title",
      "department",
      "provisional_start_date",
      "has_seniority_date",
      "seniority_date",
      "manager"
    ]
  }
}

ℹ️ Since employment data schemes are dynamic, we highly recommend dynamically generating UI forms when using the Remote API in production. Learn more from how JSON schemas work guide.

Basic information constraints

  1. Understandingprovisional_start_date validations:
    While JSON schemas define validation rules for most fields, provisional_start_date includes additional complex rules that are only enforced by the API when calling the create employment endpoint. Here's an example schema snippet:

    {
      "title": "Provisional start date",
      "format": "date",
      "x-jsf-presentation": {
        "inputType": "date",
        "meta": { "mot": 3 },
        "minDate": "2025-03-10"
      }
    }

    These key validation rules include:

    1. Minimum onboarding time (MOT): Each country has a minimum number of working days required to onboard an employee before their start date. The meta.mot field defines this in the schema. For example, if today is March 10 and the MOT is 3 days, the the selected date needs to be March 13 or after. This is included in the JSON schema shown above.
    2. Weekends: Some countries do not allow start dates on weekend, which may differ globally.
    3. Holidays: National holidays may restrict start dates in some countries.
    4. Arbitrary dates: Certain days (e.g., Christmas Eve) may not be allowed as a starting date.
      The Remote API enforces these rules and if a request violates any of them, an error response will be thrown explaining the issue.
  2. Validation Flow:

    The onboarding process may take several days. You can use the meta.mot to implement an expiration system that notifies customers if a selected date becomes invalid. For example, let's say the MOT is 3 days, with today being Monday and the selected start date falls on Friday. The days have passed and now it's Thursday but the customer has not finished the onboarding flow yet, in that case the start date will be no longer valid. Through meta.mot, you can automatically notify your customer about it.

Awesome. Now, you have the prereqs in place to create your first employment. Head over to the next guide to find the steps required to create an employment.