When to use this endpoint

Use for CRM1 Add/Edit Links when the server should attempt to discover a site-root frame hint and icon. The bookmark is committed before optional discovery, so a saved warning must not be retried as a new create.

Authentication and permissions

Authenticate with signed API-key fields or a logged-in CRM session. All bookmark endpoints require Settings Links View (pageSettingsLinks_view); client administrators pass the standard permission helper. Missing permission fails closed. An API key acts as its associated user.

The authenticated tenant owns the rows. Reads expose userID=0 (shared) and the acting user’s rows, even for admins. Writes to existing rows require ownership unless the actor is a client administrator; non-admins cannot edit/delete shared rows. No bookmark-specific tenant setting, department filter or separate create/edit role is consulted.

Parameters

ParameterTypeRequiredDescription
idPositive integer or zeroNoOmitted, zero or blank means create; positive canonical ID means update an existing editable row. Other invalid values fail.
nameStringYesTrimmed nonblank label; no uniqueness or explicit maximum length.
urlHTTP(S) URL stringYesTrimmed, nonblank, lowercase http:// or https:// prefix with a host. Credentials and whitespace/control characters fail. Internal destinations may be saved, but server discovery is skipped with a saved warning.

Example request

$saved = FM_api('Link_save', ['name'=>'Operations handbook', 'url'=>'https://example.test/handbook/']);

Example response

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

Optional discovery/storage failure instead adds saved=1 and warning text to the same ok/id reply. This means the bookmark exists; refresh it rather than repeating creation.

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"}Missing page access, non-owned existing write target, or forbidden ownership assignment.
{"error":"missing or invalid parameter: id/ids"}Invalid explicit ID selector; absent required selectors can instead report missing or invalid parameter: id.
{"error":"Bookmark not found or not editable"}An update target does not exist.
{"error":"Unable to save bookmark changes. Check the saved state before retrying."}Failed database/history operation or uncertain commit. Read failures instead return Unable to read bookmarks.
{"error":"url must begin with http:// or https://"}URL lacks the case-sensitive lowercase prefix. Missing/blank/invalid name or URL reports missing or invalid parameter: name/url.

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

Behaviour and edge cases

  • Creation uses shared ownership for admins and personal ownership otherwise. Updates retain ownership and require an existing editable ID. Request userID/canBeEmbedded values are ignored. Name and URL validation precedes the login check.
  • The initial committed embedding hint is 0. Discovery requests the site root rather than the saved path; a successful response without X-Frame-Options or CSP frame-ancestors permits a stored hint of 1. This remains a hint, not a browser policy guarantee.
  • Discovery allows only ports 80/443 and public IP destinations. Every DNS A/AAAA answer must be public; mixed/internal/reserved answers skip fetching. The verified destination is pinned for HTTP requests, proxies are disabled and redirects are not followed. HTTP calls have 2-second connect and 4-second overall limits, a 64 KiB header limit and 256 KiB body limit.
  • The root favicon.ico is converted from its first ICO frame to PNG fitting 75×56, with input/output/resource and subprocess-time limits. Conversion uses a unique private temporary directory removed after use; invalid/missing icons produce a warning rather than an empty stored file.
  • Row persistence is checked before remote requests. Metadata-hint and fileslib work follows the primary commit and can fail independently. The warning does not undo the bookmark.
  • Native request arrays are required where stated; JSON strings are not decoded. No direct mobile app/m-service caller for this Settings-bookmark family was found. Bookmark IDs are unrelated to document share tokens.

Side effects

  • Writes tenant links and invalidates its cache. Creation and changed mapped fields receive individual tenant history rows with acting-user attribution; deletion records a deletes audit. Database changes and history are transactional, including a multi-ID batch. A failed read, write or history operation fails the request and rolls back the batch. An uncertain commit is not automatically replayed: refresh before retrying.
  • May resolve DNS and perform two bounded root/favicon requests, invoke ImageMagick convert, and replace the icon through fileslib with type_enum=15/type_id=bookmark ID and acting-user attribution. Requires cURL, DNS, ImageMagick/process execution and fileslib for discovery only. No email or share token is created.

See it in Fieldmotion

CRM1

Settings → Links opens pageSettingsLinkEdit. It keeps the dialog on an API error; a positive saved ID closes/reloads the list and displays any saved warning.

CRM2

No production CRM2 caller found. Its mapped editor stores text directly without remote discovery.

Related endpoints