When to use this endpoint

Create one availability target/event using the camel-cased CRM2 contract. Choosing several targets in the UI produces separate create requests; this endpoint does not accept a target array.

Authentication and permissions

Authenticate with signed API-key fields or a logged-in CRM session. Uses the authenticated tenant’s data. Requires pageAvailability_add. Client administrators and full-access roles are allowed. Other roleless users are denied; signed API keys use the key owner’s role. These are page/action permissions, not an employee-ownership or HR-profile approver-list restriction.

Management calls reject accounts with features2.disableHREnhancements=1, returning HR enhancements are disabled. The helper reads the account’s current global feature value before falling back to session values. Browser permission checks are not server-side authorization.

Parameters

ParameterTypeRequiredDescription
objTypeStringYesOne of company, department, role, user. Case-sensitive after trimming.
objIDIntegerFor non-company targetsCompany forces zero. Other targets require an existing tenant target row; active/deleted state is not checked. Defaults to zero.
eventTypeStringYesAllowed names: absence, annual_leave, sick_leave, unpaid_leave, public_holiday, company_holiday, unavailable, available_override. Omitted becomes an invalid empty name, not absence.
availabilityInteger flagNoZero means unavailable, any nonzero integer-converted value means available. Defaults to zero; event_type does not supply it.
statusIntegerNo0 pending, 1 approved, 2 rejected, 3 cancelled; other integer-converted values are rejected. Defaults to pending.
nameStringNoTrimmed event label; blank is accepted. Defaults to empty.
startE / endEUnix secondsYesStart must be positive and end later than start after optional all-day normalization. Omitted values initially become zero.
allDayInteger flagNoTruthy integer enables account-local midnight normalization; otherwise use supplied epochs. Defaults to zero.
paidInteger flagNoTruthy integer means paid; no automatic inference from event type. Defaults to zero.
requestedByIntegerNoRequester attribution, not an authority check. Zero/omitted resolves to existing requester or authenticated user; supplied nonzero IDs are not validated as existing users.
notesStringNoTrimmed text. Defaults to empty.
metaNative array or JSON textNoMetadata defaults to an empty array. Invalid/non-array decoded JSON becomes an empty array.
Legacy mapped controlsMixedIgnoredClient-supplied lastEdited, dDate, approvedBy, approvedAt, metaLeaveDays, noRecord and noRecordCustom do not enter the mapped writer. Server values own cDate/createdBy/lastEdited/deleted/dDate and approval attribution; calculated meta.leave_days replaces any supplied total.

Example request

$result = FM_api('Availability_createData', [
	'objType' => 'user',
	'objID' => '71',
	'eventType' => 'annual_leave',
	'startE' => '1793005200',
	'endE' => '1793034000',
	'name' => 'Annual leave',
	'paid' => '1',
]);

Example response

{"ok":1,"id":1042}

The mapped helper returns an insert-ID envelope, not the full event. Use Availability_list or getDataTable afterwards. Saved follow-up warnings preserve this ID; never create another record merely because a follow-up failed.

Errors and unusual responses

ResponseCondition
{"error":"not logged in"}No authenticated tenant context is available. Invalid signed credentials can be rejected by the dispatcher before the handler runs.
{"error":"permission denied"}The authenticated actor lacks the required page/action permission.
{"error":"HR enhancements are disabled"}The account has disabled HR enhancements.
{"error":"invalid obj_type"}Target type is not company, department, role, or user.
{"error":"missing or invalid obj_id"}A non-company target has an integer-converted ID less than one.
{"error":"target does not exist"}No tenant row exists for the selected non-company target. This lookup does not impose an active/deleted target filter.
{"error":"invalid event_type"}The event type is outside the eight-name allowlist.
{"error":"invalid status"}The integer-converted status is outside 0–3.
{"error":"invalid start/end time"}After optional all-day normalization, start/end are nonpositive or end is not later than start.
{"error":"Unable to create record"}The generic helper’s primary insert failed or yielded no positive ID.

Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.

Behaviour and edge cases

  • Event ranges are half-open: [start_e,end_e). Epoch values are Unix seconds, not milliseconds. With all-day enabled, the helper converts both epochs to account-local dates and replaces them with local midnights. If the normalized end is not later than the start, it becomes the next local midnight. A multi-day end date therefore remains exclusive; include the following midnight when the UI’s final date is inclusive.
  • The event type label does not force availability, status, or paid. For example, an annual-leave event may be stored as available; approved annual-leave usage still keys on event type and status, not those flags. No overlap or entitlement-limit validation is performed.
  • Unlike raw save, eventType is required in practice: the wrapper supplies an empty default, which fails the type allowlist. An input id is not used to update an event.
  • Computes meta.leave_days from the validated time range before the checked insert, preserving other metadata. This applies to every event type/status, not just approved annual leave. It no longer makes a nested Availability_updateData call.
  • After the insert, recalculates annual-leave usage and evaluates configured create/time notifications. Creation does not evaluate update notification rules as an artificial metadata follow-up.
  • The primary write is checked before dependent work. After saving, failed recalculation or notification work retains the normal success fields and adds saved=1 and warning. Do not repeat the write to repair a follow-up; re-read the event and investigate balances/notification history. The event, history, balances and external queues are not one atomic transaction.

Side effects

  • Inserts an active event with server creation/edit timestamps and actor attribution, dDate=0, and server approval attribution only for approved status. Invalidates availability_events cache and writes generic per-field history; caller suppression controls are ignored. History and the insert are not one atomic transaction.
  • When an old or new event is approved annual leave, the helper recalculates affected users’ stored annual-leave usage for touched years, using current company/department/role/user membership. Each account-local date touched counts as one whole day except dates in week-days-off (0 Sunday through 6 Saturday). Partial dates count as full days, year boundaries are split, and calendar arithmetic preserves DST dates. Overlapping leave events contribute separately; balances may become negative. Supported recalculation years are the server’s current year minus five through plus ten.
  • The initial insert stores meta.leave_days as the count of touched account-local dates excluding current week-days-off, while retaining other supplied metadata.
  • Uses configured availability notification rules, not the legacy hard-coded transition notices. Create evaluates create2/time2; changed update evaluates update2/time2. Rule enablement, platform, recipients, conditions and templates determine queued email/push/notices. Missing/negative service acknowledgements produce a saved follow-up warning; this is not confirmation of delivery.

See it in Fieldmotion

CRM1

No direct CRM1 caller for Availability_createData was found in the source search. The implemented management screen is CRM2’s Availability page.

CRM2

In Availability, choose Create and save the dialog. The page calls the shared createData helper with table Availability. Filter the Network panel for Availability_createData; each selected company/user/department/role target is sent separately.

Related endpoints