Welcome to NiceJob's v2 REST API. Our API accepts JSON-encoded and form-encoded request bodies, returns JSON-encoded responses, uses OAuth2 for authentication, and uses standard HTTP response codes.
The API and this documentation are still very much a work in progress. Please refer to the API CHANGELOG for the latest changes.
For authentication, we use OAuth2: a 3-step procedure comprising a user redirect for the obtainment of consent, and two subsequent client-to-NiceJob POST requests. Much has been written about OAuth2. If you are unfamiliar with it, we recommend these resources:
Use the following endpoints for your OAuth2 requests to NiceJob:
| Authorization endpoint | https://api.nicejob.com/oauth/authorize |
| Token endpoint | https://api.nicejob.com/oauth/token |
| Revocation endpoint | https://api.nicejob.com/oauth/revoke |
| Introspection endpoint | https://api.nicejob.com/oauth/introspect |
The 3 steps to obtain an access token are thus:
REDIRECThttps://api.nicejob.com/oauth/authorizeGain the user's consent by redirecting them to the authorization endpoint. We then redirect the user back to your redirect_uri, with the authorization code attached as a query parameter.
POSThttps://api.nicejob.com/oauth/tokenSend that authorization code to the token endpoint to obtain a refresh token. Use grant_type: "authorization_code".
POSThttps://api.nicejob.com/oauth/tokenSend the refresh token received above to the token endpoint to obtain an access token. Use grant_type: "refresh_token".
With the access token obtained, you are free to query the API. See the requests section of the API for information on how to format your requests.
Access tokens are valid for a period of 24 hours. You are free to refresh them at any point beforehand. To refresh an access token, repeat the get access token step above.
Refresh tokens do not expire.
In the case that you or the user would like to end the connection between applications, refresh tokens may (and should) be revoked.
To revoke a refresh token, make a POST request to the revocation endpoint using the format defined in the OAuth2 standard.
Note that webhook authentication – given that it is developer-scoped via a client_credentials grant type and not company-scoped – follows a different authentication protocol. See the Webhook authentication section below for more.
Your app's credentials – and all access tokens derived from them – are restricted to work within an array of provided scopes. You can view your app's permitted scopes by signing in and checking your app's credentials. The scope(s) required to access each endpoint are provided in the endpoint documentation below.
The NiceJob API expects incoming requests to be in JSON format, with a Content-Type: application/json header.
We return 200 status codes for all properly processed requests. Requests with malformed input data will return a 400, while unauthorized requests – including those with an expired access token – will return a 401. Server errors from our side will return a ≥500.
There are cases however where successfully formatted and authenticated requests do not produce their intended action – e.g. a creation request with a duplicated unique key. Such cases will return a 200 status code but output an error message in the response's error field.
Any successful API request (status 200) will receive, in response, a JSON object with the following fields:
cursorstring | nullnull. Use cursors to return the next page of results.dataobject | nullerrorstring | nullSee the API Changelog for the latest changes to this API.
A Booking represents a job that a user Company has arranged with one of their customers (known as a Person herein). The Booking entity can be created at the time of scheduling. Upon completion, the Booking is to be updated as complete. Booking completion will normally trigger a CampaignEnrollment, depending on the Company's Campaign settings.
If your software supports job grouping, you may want to consider creating one Booking with subordinate Visits. See the Visit entity description for more information.
idstringUniqueamountfloat | nullcompletebooleancompleted_timeDate | nullcomplete: truecreated_atDateemployee_idsArray<string>namestring | nullperson_idsArray<string>scheduled_timeDate | nulltagsArray<string>noreview tag will prevent a Booking from triggering a CampaignEnrollment on completion.updated_atDateRetrieve a paginated list of Booking entities.
GEThttps://api.nicejob.com/v2/bookings?person_id=$PERSON_ID&cursor=$CURSORcursorstring?person_idstring?Returns an array of Booking entities, up to 20 items long.
Retrieve an individual Booking entity.
GEThttps://api.nicejob.com/v2/bookings/:ididstringUniqueReturns the Booking entity if found. Returns a null result otherwise.
POSThttps://api.nicejob.com/v2/bookingsamountfloat?completeboolean?completed_timeDate?complete: truecreated_atDateemployee_idsArray<string>itemsArray<object>items[].amountobjectitems[].amount.currency_codestring?items[].amount.valueintitems[].catalog_product_idstringitems[].descriptionstring?items[].external_source_idstringitems[].namestringitems[].quantityintnamestring?person_idstring?Deprecatedperson_idsArray<string>scheduled_timeDate?tagsArray<string>noreview tag will prevent a Booking from triggering a CampaignEnrollment on completion.Returns the new Booking entity.
Updates a Booking entity. The values you provide will overwrite any previously-existing values on the entity.
POSThttps://api.nicejob.com/v2/bookings/:ididstringUniqueamountfloat?completeboolean?completed_timeDate?complete: truecreated_atDateemployee_idsArray<string>itemsArray<object>items[].amountobjectitems[].amount.currency_codestring?items[].amount.valueintitems[].catalog_product_idstringitems[].descriptionstring?items[].external_source_idstringitems[].namestringitems[].quantityintnamestring?person_idstring?Deprecatedperson_idsArray<string>scheduled_timeDate?tagsArray<string>noreview tag will prevent a Booking from triggering a CampaignEnrollment on completion.Returns the updated Booking entity, if found. Returns a null result otherwise.
A Case represents a legal case that a user Company has arranged with one of their customers (known as a Person herein). Upon completion, the Case is to be updated as complete. Case completion will normally trigger a CampaignEnrollment, depending on the Company's Campaign settings.
idstringUniquecompleted_timeDate | nullcreated_atDatedescriptionstring | nullemployee_idsArray<string>namestring | nullperson_idstringstatusEnum<"pending" | "open" | "closed"> | nulltagsArray<string>updated_atDateRetrieve a paginated list of Case entities.
GEThttps://api.nicejob.com/v2/cases?person_id=$PERSON_ID&cursor=$CURSORcursorstring?person_idstring?Returns an array of Case entities, up to 20 items long.
Retrieve an individual Case entity.
GEThttps://api.nicejob.com/v2/cases/:ididstringUniqueReturns the Case entity if found. Returns a null result otherwise.
POSThttps://api.nicejob.com/v2/casescompleted_timeDate?created_atDatedescriptionstring?employee_idsArray<string>namestring?person_idstring?statusEnum<"pending" | "open" | "closed">?tagsArray<string>Updates a Case entity. The values you provide will overwrite any previously-existing values on the entity.
POSThttps://api.nicejob.com/v2/cases/:ididstringUniquecompleted_timeDate?created_atDatedescriptionstring?employee_idsArray<string>namestring?person_idstring?statusEnum<"pending" | "open" | "closed">?tagsArray<string>Returns the updated Case entity, if found. Returns a null result otherwise.
Campaigns are the heart of NiceJob: they're the primary vehicle through which we provide value for our users. Campaigns consist of a sequence of messages between Company and Person (client), through which the company makes a request of the client.
NiceJob provides a series of campaigns, though the only one currently accessible through the API is the Get Reviews campaign.
For a Person to start receiving campaign messages, they must be enrolled.
idstringUniquecreated_atDatedescriptionstring | nullnamestringobjectiveEnum<"REVIEWS" | "RECOMMENDATIONS" | "EMPLOYEE_REVIEWS" | "ENGAGEMENT" | "BOOKINGS" | "WELCOME_NEW_CUSTOMERS" | "REWARD_LOYAL_CUSTOMERS" | "REPEAT_BUSINESS" | "REFERRALS"> | nullsubject_kindEnum<"Person" | "Story" | "Employee" | "User">updated_atDateRetrieve a list of Campaign entities.
GEThttps://api.nicejob.com/v2/campaignsReturns an array of Campaign entities.
Campaign enrollments can be created in one of two ways: indirectly or directly. Indirect enrollment
Indirect enrollment occurs in response to Booking completion (wherein the Booking created with complete: true, or the complete field is updated to true), and is subject to the user's NiceJob settings. This is the recommended mode of enrollment: create the Booking entity, and let NiceJob take care of the rest. Direct enrollment
In some cases however, we permit direct enrollment of a Person into a campaign via the API. This is conveyed through the enrollments scope. Enrollment is conditional
Campaigns have rules that prevent multiple enrollments of the same Person. Therefore direct enrollment requests may not result in the creation of a CampaignEnrollment entity. Such requests will still return a 200 status code, but will have a null data field and an error message in the error field.
Direct enrollments will also fail where insufficient Person information is provided. Either an email address or a phone number is requred.
idstringUniquecampaign_idstringcreated_atDateemployee_idsArray<string>tagsArray<string>updated_atDateAttempts to enroll a Person into a given campaign, defaulting to the Company's Get Reviews campaign.
POSThttps://api.nicejob.com/v2/campaign_enrollmentscampaign_idstring?person_idstringReturns the new CampaignEnrollment entity, if successfully created.
The Company is the foundational entity in NiceJob. All other entity types fall within the company namespace. Access tokens are not tied to the authenticating user's user data but rather to the data of one of their companies.
idstringUniqueaddressobject | nulladdress.addressstring | nulladdress.citystring | nulladdress.countrystring | nulladdress.statestring | nulladdress.unitstring | nulladdress.zipstring | nullcompany_namestringcreated_atDateemailstring | nulllanguage_preferencestring | nullmigrated_fromEnum<"paystone_hub"> | nullowner_first_name_overridestring | nullowner_last_name_overridestring | nullphonestring | nullplatformstring | nullslugstring | nullupdated_atDatewebsitestring | nullRetrieve the access token-bound Company entity.
GEThttps://api.nicejob.com/v2/companyReturns the Company entity to which the access token is bound.
An Employee represents an employee of the Company. Given that the Company manages the NiceJob account, the employee may also be a NiceJob User. Employees are often attached to Bookings.
Employee is referred to as Team member in app.idstringUniquearchived_atDate | nullcreated_atDateemailstringUniquefirst_namestringlast_namestring | nullphonestring | nullpositionstring | nullupdated_atDateRetrieve a paginated list of Employee entities.
GEThttps://api.nicejob.com/v2/employees?email=$EMAIL&cursor=$CURSORcursorstring?emailstring?Returns an array of Employee entities, up to 20 items long.
Retrieve an individual Employee entity.
GEThttps://api.nicejob.com/v2/employees/:ididstringUniqueReturns the Employee entity if found. Returns a null result otherwise.
POSThttps://api.nicejob.com/v2/employeesarchived_atDate?emailstringUniquefirst_namestringlast_namestring?phonestring?positionstring?Returns the new Employee entity.
Updates an Employee entity. The values you provide will overwrite any previously-existing values on the entity.
POSThttps://api.nicejob.com/v2/employees/:ididstringUniquearchived_atDate?emailstring?Uniquefirst_namestring?last_namestring?phonestring?positionstring?Returns the updated Employee entity, if found. Returns a null result otherwise.
idstringUniquebalancefloatcreated_atDatecurrencystring | nulldescriptionstring | nulldiscountsArray<object>discounts[].amountfloat | nulldiscounts[].descriptionstring | nulldiscounts[].namestring | nulldiscounts[].percentagefloat | nullemployee_idsArray<string>lineArray<object>line[].amountfloat | nullline[].descriptionstring | nullnamestring | nullpaidbooleanpaid_atDate | nullperson_idstring | nullperson_idsArray<string>statusEnum<"draft" | "open" | "paid" | "uncollectible" | "void"> | nullsubtotalfloat | nulltagsArray<string>taxesArray<object>taxes[].amountfloat | nulltaxes[].descriptionstring | nulltaxes[].namestring | nulltaxes[].percentagefloat | nulltotalfloatupdated_atDateRetrieve a paginated list of Invoice entities.
GEThttps://api.nicejob.com/v2/invoices?person_id=$PERSON_ID&cursor=$CURSORcursorstring?person_idstring?Returns an array of Invoice entities, up to 20 items long.
Retrieve an individual Invoice entity.
GEThttps://api.nicejob.com/v2/invoices/:ididstringUniqueReturns the Invoice entity if found. Returns a null result otherwise.
POSThttps://api.nicejob.com/v2/invoicesidstringUniquebalancefloatcreated_atDatecurrencystring?descriptionstring?discountsArray<object>discounts[].amountfloat?discounts[].descriptionstring?discounts[].namestring?discounts[].percentagefloat?employee_idsArray<string>lineArray<object>line[].amountfloat?line[].descriptionstring?namestring?paidboolean?paid_atDate?person_idstring?person_idsArray<string>statusEnum<"draft" | "open" | "paid" | "uncollectible" | "void">?subtotalfloat?tagsArray<string>taxesArray<object>taxes[].amountfloat?taxes[].descriptionstring?taxes[].namestring?taxes[].percentagefloat?totalfloatReturns the new Invoice entity.
Updates an Invoice entity. The values you provide will overwrite any previously-existing values on the entity.
POSThttps://api.nicejob.com/v2/invoices/:ididstringUniquebalancefloat?created_atDatecurrencystring?descriptionstring?discountsArray<object>discounts[].amountfloat?discounts[].descriptionstring?discounts[].namestring?discounts[].percentagefloat?employee_idsArray<string>lineArray<object>line[].amountfloat?line[].descriptionstring?namestring?paidboolean?paid_atDate?person_idstring?person_idsArray<string>statusEnum<"draft" | "open" | "paid" | "uncollectible" | "void">?subtotalfloat?tagsArray<string>taxesArray<object>taxes[].amountfloat?taxes[].descriptionstring?taxes[].namestring?taxes[].percentagefloat?totalfloat?Returns the updated Invoice entity, if found. Returns a null result otherwise.
idstringUniqueamountfloatamount_refundedfloat | nullcreated_atDatecurrencystring | nulldescriptionstring | nulldisputedbooleanemployee_idsArray<string>invoice_idsArray<string>person_idsArray<string>refundedbooleanstatusEnum<"succeeded" | "pending" | "failed"> | nulltagsArray<string>updated_atDateRetrieve a paginated list of Payment entities.
GEThttps://api.nicejob.com/v2/payments?id=$IDidstringUniqueReturns an array of Payment entities, up to 20 items long.
Retrieve an individual Payment entity.
GEThttps://api.nicejob.com/v2/payments/:ididstringUniqueReturns the Payment entity if found. Returns a null result otherwise.
POSThttps://api.nicejob.com/v2/paymentsidstringUniqueamountfloatamount_refundedfloat?created_atDatecurrencystring?descriptionstring?disputedboolean?employee_idsArray<string>invoice_idsArray<string>person_idsArray<string>refundedboolean?statusEnum<"succeeded" | "pending" | "failed">?tagsArray<string>Returns the new Payment entity.
Updates an Payment entity. The values you provide will overwrite any previously-existing values on the entity.
POSThttps://api.nicejob.com/v2/payments/:ididstringUniqueamountfloat?amount_refundedfloat?created_atDatecurrencystring?descriptionstring?disputedboolean?employee_idsArray<string>invoice_idsArray<string>person_idsArray<string>refundedboolean?statusEnum<"succeeded" | "pending" | "failed">?tagsArray<string>Returns the updated Payment entity, if found. Returns a null result otherwise.
A Person represents a company client, or customer.
idstringUniqueaddressobject | nulladdress.addressstring | nulladdress.citystring | nulladdress.countrystring | nulladdress.statestring | nulladdress.unitstring | nulladdress.zipstring | nullblockedbooleancompanystring | nullcreated_atDateemailstring | nullUniquefirst_namestring | nullinitial_sourcestring | nulllast_namestring | nulllifecycle_stagestring | nullphonestring | nullpositionstring | nulltagsArray<string>updated_atDateRetrieve a paginated list of Person entities.
GEThttps://api.nicejob.com/v2/people?email=$EMAIL&cursor=$CURSORcursorstring?emailstring?Returns an array of Person entities, up to 20 items long.
Retrieve an individual Person entity.
GEThttps://api.nicejob.com/v2/people/:idReturns the Person entity if found. Returns a null result otherwise.
POSThttps://api.nicejob.com/v2/peopleaddressobject?address.addressstring?address.citystring?address.countrystring?address.statestring?address.unitstring?address.zipstring?blockedboolean?companystring?emailstring?Uniquefirst_namestring?initial_sourcestring?last_namestring?lifecycle_stagestring?phonestring?positionstring?tagsArray<string>Returns the new Person entity.
Updates a Person entity. The values you provide will overwrite any previously-existing values on the entity.
POSThttps://api.nicejob.com/v2/people/:ididstringUniqueaddressobject?address.addressstring?address.citystring?address.countrystring?address.statestring?address.unitstring?address.zipstring?blockedboolean?companystring?emailstring?Uniquefirst_namestring?initial_sourcestring?last_namestring?lifecycle_stagestring?phonestring?positionstring?tagsArray<string>Returns the updated Person entity, if found. Returns a null result otherwise.
A Review represents a company review on a particular network.
idstringUniqueauthorstring | nullauthor_emailstring | nullcreated_atstringmicrosite_urlstring | nullnetworkstring | nullperson_idstring | nullratingfloat | nullsource_base_urlstring | nullsource_urlstring | nullRetrieve a paginated list of Review entities.
GEThttps://api.nicejob.com/v2/reviews?id=$ID&person_id=$PERSON_IDidstringUniqueperson_idstring?Returns an array of Review entities, up to 20 items long.
Retrieve an individual Review entity.
GEThttps://api.nicejob.com/v2/reviews/:ididstringUniqueReturns the Review entity if found. Returns a null result otherwise.
The ReviewInsights entity provides an aggregate summary of a company's online reviews.
average_ratingfloatnetwork_insightsArray<object>network_insights[].average_ratingfloatnetwork_insights[].networkstringnetwork_insights[].review_countintreview_countintRetrieve the ReviewInsights entity.
GEThttps://api.nicejob.com/v2/review_insights?person_id=$PERSON_IDperson_idstring?Returns the ReviewInsights entity.
Many job management softwares will distinguish between a job and its constituent parts – the visits, or segments, that comprise it. We provide the same functionality here: a Visit entity is the child entity of a Booking.
A Visit has a required booking_id property – therefore the Booking must be created before the Visit. A Booking, meanwhile, does not necessarily have to include Visits.
Note that – unlike with Bookings – a NiceJob user will have to update their Company's Campaign settings should they want a Visit completion to trigger the creation of a CampaignEnrollment. Campaign settings cannot be updated through the API.
If you wish to have a Visit trigger a CampaignEnrollment, consider just using Bookings instead, or notify your users of the necessity to update their NiceJob Campaign settings.
Upon completion, a Visit is to be updated as complete.
idstringUniqueamountfloat | nullbooking_idstringcompletebooleancompleted_timeDate | nullcreated_atDateemployee_idsArray<string>namestring | nullperson_idstringscheduled_timeDate | nulltagsArray<string>updated_atDateRetrieve a paginated list of Visit entities.
GEThttps://api.nicejob.com/v2/visits?person_id=$PERSON_ID&cursor=$CURSORcursorstring?person_idstring?Returns an array of Visit entities, up to 20 items long.
Retrieve an individual Visit entity.
GEThttps://api.nicejob.com/v2/visits/:ididstringUniqueReturns the Visit entity if found. Returns a null result otherwise.
POSThttps://api.nicejob.com/v2/visitsamountfloat?booking_idstringcompleteboolean?completed_timeDate?created_atDateemployee_idsArray<string>namestring?person_idstringscheduled_timeDate?tagsArray<string>Updates a Visit entity. The values you provide will overwrite any previously-existing values on the entity.
POSThttps://api.nicejob.com/v2/visits/:ididstringUniqueamountfloat?booking_idstring?completeboolean?completed_timeDate?created_atDateemployee_idsArray<string>namestring?person_idstring?scheduled_timeDate?tagsArray<string>Returns the updated Visit entity, if found. Returns a null result otherwise.
NiceJob webhooks allow you to receive a notification whenever a change occurs to a company's data. The process for creating a webhook is as follows:
endpoint_url is the fully-qualified URL of your new endpoint, and specify one or more entity types (subscriptions) with which this webhook is associated. See the subscriptions list below.A NiceJob webhook is company-independent. Instead, it is linked to your developer account. This means that you only need to establish a single webhook endpoint for all company connections, and not one endpoint for each company connection. This approach makes it much easier to manage your webhooks: for example when changing your webhook subscriptions, or changing a webhook endpoint. An example workflow is as follows:
Person-related event is published within NiceJob.Person entity.Person entity in-scope.The webhook endpoint is linked to your developer account, and as such does not require OAuth2 user authorization to manage (as defined in the Authentication section above). Thus the webhook endpoint requires an access token provided using the grant_type: "client_credentials" OAuth2 flow as described here.
The access token provided using the client_credentials flow has a limited set of scopes for managing entities associated with your developer account.
POSThttps://api.nicejob.com/oauth/tokenGenerates a client_credentials access token using your client ID and client secret, and the "client_credentials" grant type.
idstringUniquecreated_atDateendpoint_urlstringis_enabledbooleansecretstringsubscriptionsArray<Enum<"Person" | "Job" | "Invoice" | "Conversation" | "Story" | "Photo" | "Campaign" | "CampaignEnrollment" | "Employee" | "Review" | "Case" | "Payment" | "notifications">>updated_atDateValid subscriptions values are:
"Campaign""CampaignEnrollment""Case""Conversation""Employee""Invoice""Job""Payment""Person""Photo""Review""Story"GEThttps://api.nicejob.com/v2/webhooks?cursor=$CURSORcursorstring?Returns an array of Webhook entities, up to 20 items long.
Retrieve an individual Webhook entity.
GEThttps://api.nicejob.com/v2/webhooks/:ididstringUniqueReturns the Webhook entity if found. Returns a 401 HTTP status code if not found.
Create a new Webhook entity.
POSThttps://api.nicejob.com/v2/webhooksendpoint_urlstring?subscriptionsArray<Enum<"Person" | "Job" | "Invoice" | "Conversation" | "Story" | "Photo" | "Campaign" | "CampaignEnrollment" | "Employee" | "Review" | "Case" | "Payment" | "notifications">>Returns the new Webhook entity.
Updates a Webhook entity.
The subscriptions property of UpdateWebhookInput is immutable. Therefore for an update, you must provide the whole new subscriptions value which will replace the existing subscriptions value.
POSThttps://api.nicejob.com/v2/webhooks/:ididstringUniqueendpoint_urlstring?is_enabledboolean?subscriptionsArray<Enum<"Person" | "Job" | "Invoice" | "Conversation" | "Story" | "Photo" | "Campaign" | "CampaignEnrollment" | "Employee" | "Review" | "Case" | "Payment" | "notifications">>Returns the updated Webhook entity.
Deletes a Webhook entity.
DELETEhttps://api.nicejob.com/v2/webhooks/:ididstringUniqueReturns the deleted Webhook entity.
Outbound webhook requests are application/json POST requests, with the body data structured as follows:
payloadobjectpayload.company_idstringpayload.entity_idstringpayload.event_codestringsignatureobjectsignature.signed_payloadstringsignature.timestampintNote that we only provide the entity_id of the entity affected, as well as the event_code, which will confer the entity type. Use the entity endpoints to retrieve the updated entity information.
On webhook creation, a secret will be generated and returned in the response. This is the only time the secret will be shared.
Each Webhook publication will contain a signature which will be composed of two properties: a timestamp and a signed payload. The timestamp will be Unix-format and be appended to the request immediately prior to dispatch.
The signed payload will be a HMAC using the SHA-256 algorithm. In order to validate the signature, one must:
secret property (shared on webhook creation)signed_payload property from the received messageThe timestamp is generated immediately prior to dispatch. You should compare the timespan between now and the timestamp to see how much time has elapsed and ensure it is within your security tolerances.
The failure condition for delivery of a Webhook is that we receive a non-2xx HTTP response. When this happens, NiceJob will retry for up to 3 days with an exponential back off. At this point your webhook endpoint will be disabled and we will attempt to inform you via email. Once you have resolved the issue, you can re-enable your webhook using the Update Webhook endpoint by setting the is_enabled property to true.
When invoking a Webhook delivery through the Test Webhook endpoint, there are no retries and your endpoint will not be disabled.
For development purposes, we have provided a method of invoking a mock webhook publication for a specific subscription. If you have a webhook registered for the subscription, we will publish to that endpoint with the mock payload.
POSThttps://api.nicejob.com/v2/rpc/test-webhookmock_payloadobjectmock_payload.company_idstringmock_payload.entity_idstringmock_payload.event_codestringsubscriptionEnum<"Person" | "Job" | "Invoice" | "Conversation" | "Story" | "Photo" | "Campaign" | "CampaignEnrollment" | "Employee" | "Review" | "Case" | "Payment" | "notifications">Returns a HTTP status code where a 200 indicates a webhook has been found for the provided subscription and it has been successfully queued for publishing.