When to use this endpoint

Use when an integration needs a URL that another person can open without a CRM login. Send or open the returned url; do not invent a CRM file path or confuse the returned link ID with the underlying object ID. The token permits future access to that object, not just a single immediate download.

Authentication and permissions

Authenticate with signed API-key fields or a logged-in CRM session. The handler requires an authenticated tenant and View permission for the object page: Jobs, Files, Invoices, Quotes or Purchase Orders. Credit Notes use Invoices View and require accounting_credit_notes=1. The legacy finance restriction (crm_access bit 64) blocks invoice, quote, purchase-order and credit-note shares.

The dispatcher and handler enforce TeamAccess when the actor has configured scoped access: only obj_type=0 is permitted and the job must be visible in that actor’s Job scope. Other types return This share requires a supported scoped record. These scope checks apply in addition to page/finance/file guards, including nested calls.

Parameters

ParameterTypeRequiredDescription
obj_idIntegerYesUnderlying job/file/invoice/quote/purchase-order/credit-note ID, not a link ID. Must be a canonical positive integer within the platform integer range. Zero, negative, malformed and overflowing values fail. The active object must exist; quotes/purchase orders require form_id>0 and files exclude type_enum=10.
obj_typeIntegerYesOnly integer/string 0,1,2,3,5,6 accepted, with meanings below. Other types fail without creating a token.
noteStringNoIf present/non-null, a string saved as meta.note via checked JSON encoding. It is descriptive metadata, not a download permission, recipient restriction or expiry control. Other top-level controls such as edate/onetime do not change the handler’s stored lifetime.

Example request

$link = FM_api('LinkShareable_new', [
	'obj_id' => '1042',
	'obj_type' => '0',
	'note' => 'Shared job report',
]);

Example response

{"ok":1,"id":1088,"url":"https://p.fieldmotion.com/linkshareable/?pid=1042&id=1088&code=0123456789abcdef0123456789abcdef","pid":"1042","code":"0123456789abcdef0123456789abcdef"}

id is the new link-row ID (integer insert-helper result); pid is the authenticated tenant ID and can be a session string. code is a newly generated lowercase 32-hex string from 16 cryptographically random bytes; the example is a placeholder, not a working token. url embeds tenant ID, link ID and code.

The base URL uses deployment configuration LINKSHAREABLE_URL, falling back to https://p.fieldmotion.com/linkshareable/. This is not a per-tenant request setting. No object data, binary bytes, filename or expiry field is returned.

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":"missing parameter: obj_id"}obj_id absent/null.
{"error":"missing parameter: obj_type"}obj_type absent/null.
{"error":"permission denied"}Missing object-page or file access; scope denial can return its own error.
{"error":"Object not found or not shareable"}Missing/deleted target, or a quote/purchase order without a positive form. Invalid IDs/types fail validation first.
{"error":"Unable to create share link. Check saved links before retrying."}Database lookup/insert failure, invalid metadata encoding or uncertain persistence; no url/code returned.
{"error":"This share requires a supported scoped record."}Scoped TeamAccess actor requests a non-job type. Job visibility can separately deny a job share.

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

Behaviour and edge cases

  • Inserts a new tenant links_shareable row on every call, with current Unix cdate, edate=now+365×86400 seconds, random code and JSON metadata. This is not idempotent and does not reuse an existing share for the same object. Request-supplied tenant/user IDs do not switch the authenticated tenant.
  • The insert must return a positive ID before any URL/code is returned. Lookup/insert failures return an error without a bearer token. An uncertain acknowledgement is not retried automatically; check saved links first. Creation validates object access but does not render a report or fetch file bytes, so later rendering/storage failures remain possible.
  • The canonical download service accepts GET and HEAD, with no CRM session/cookie requirement. It validates positive tenant/link IDs and the 32-hex code against the tenant’s stored token using a constant-time comparison. Anyone holding the complete URL can use it; there is no second recipient or CRM-role check at download time.
  • Supported object types are 0=job report, 1=stored file, 2=invoice, 3=quote, 5=purchase order and 6=credit note. Other types or nonpositive stored object IDs yield Download not found. Document rows must be active; quotes/purchase orders additionally require form_id>0. Stored files must be active and type_enum=10 is excluded.
  • The service deliberately does not read/enforce edate or one-time metadata. A stored one-year expiry is informational, not a guarantee that the URL expires. Repeated GETs remain possible while the token and accessible object exist; this contract is preserved for legacy links.
  • GET generates the current document through the report service, rather than serving a snapshot captured when the token was created. Document responses must contain a valid PDF; non-PDF job output can be converted through the configured document converter. Renderer transport/invalid-response/busy failures are retried up to three attempts with about 1.1 seconds between attempts; permanent renderer errors fail without that retry. Stored files are read through fileslib with the service’s legacy-path fallback.
  • HEAD is metadata-only: it validates the object and returns filename/type (plus stored-file size when known) without generating reports, reading file bytes or recording a successful GET audit. HEAD success does not prove subsequent report rendering or archived byte retrieval will succeed.
  • Public service errors are plain text with HTTP status: 400 Invalid request for invalid identifiers/code, 404 Download not found for token/object/type absence, 405 Invalid request with Allow: GET, HEAD for other methods, and 503 Download temporarily unavailable for a failed download-resolution operation. These are service responses, not JSON errors from the CRM redirect handler.

Side effects

  • Creates only the token row; no email, notification, object update, report rendering, creation audit or explicit cache invalidation is invoked. A later successful service GET attempts a tenant linkshareable/get log entry with object metadata and requester IP, but not the token. Stored-file access may rehydrate archived bytes through fileslib.

See it in Fieldmotion

CRM1

No direct production CRM1 caller for LinkShareable_new was found. Related real producers create token rows internally: the public Job signature view supplies its document link, and Support_send creates attachment links in the support email. Those are distinct entrypoints, not evidence the browser calls this RPC.

CRM2

No direct production CRM2 caller for LinkShareable_new was found. Support attachments use Support_send’s internal token creation. In the app, opening a job report calls m’s syncDownloadOne with jobReportURL-<job ID>; m inserts its own token and returns the canonical service URL, which the browser/native external opener then opens. It does not call this CRM RPC.

Related endpoints

  • LinkShareable_new creates a new bearer link and returns the canonical download-service URL.
  • LinkShareable_get redirects old CRM URLs; it does not itself download a file or generate a report.
  • Link_save saves a Settings bookmark and favicon, a separate workflow with unrelated IDs.