If you have not looked at the Execute FileMaker Data API script step (often shortened to eDAPI) in a while, it’s worth a revisit. Recent versions let you read and write records, including create, update, delete, and duplicate, by sending a small JSON request. You can do this without moving users around layouts and without calling the server’s web Data API. The step runs inside your file (hosted or local) and returns clear JSON that works well with web viewers, JavaScript, and external services. help.claris.com
What changed
Full CRUD + metadata. The action key supports read, metaData, create, update, delete, and duplicate. help.claris.com
Context-independent. Point to a layout in your JSON and eDAPI uses that context. No Go to Layout/Commit sequencing. help.claris.com
Local or hosted. It runs in your file and does not make a web service call to the Data API. help.claris.com
JSON in / JSON out. Pair with Get ( LastError ), Get ( LastErrorDetail ), and Get ( LastErrorLocation ) for diagnostics. help.claris.com
Concurrency-aware. Use modId on updates for optimistic concurrency. help.claris.com
Additional control. version supports v1, v2, vLatest; options.entrymode and options.prohibitmode let you follow or override validation/auto-enter rules when you need to. help.claris.com
Why teams find it useful
Shorter scripts. Many tasks become “build JSON → run one step.”
Fewer context issues. Read and write without leaving the user’s current layout.
Better interoperability. The JSON request/response makes it easy to work with web viewers, JavaScript, and Claris Connect.
Safer updates. modId helps avoid accidental overwrites when multiple users are editing.
Quick reference (keys you’ll use often)
action: read | metaData | create | update | delete | duplicate
layouts: target layout name (defines context)
tables: table occurrence name (for metaData)
query: array of find objects (standard FileMaker find operators)
recordId: internal ID for update/delete/duplicate
sort, offset, limit
fieldData: object of field:value pairs
portalData: object keyed by portal/TO name → array of related rows
modId: optimistic concurrency on update
layout.response: different layout for the response context (e.g., summary fields)
version: v1 | v2 | vLatest
options.entrymode: user | script
options.prohibitmode: user | script help.claris.com
Patterns and examples
Each example builds Request with JSONSetElement. Store the result in a variable and pretty-print with JSONFormatElements ( $$result ) while developing. Replace layout and field names with your own.
1) Read with a find and sort
// Returns last 100 paid orders from 2025, newest first
Execute FileMaker Data API [ Select ; Target: $$result ;
JSONSetElement ( “{}” ;
[ “layouts” ; “Orders_list” ; JSONString ] ;
[ “query” ; “[ { \”Status\”:\”Paid\” , \”OrderDate\”:\”>=1/1/2025\” } ]” ; JSONArray ] ;
[ “sort” ; “[ { \”fieldName\”:\”OrderDate\” , \”sortOrder\”:\”descend\” } ]” ; JSONArray ] ;
[ “limit” ; 100 ; JSONNumber ]
)
]
Set Variable [ $$result ; JSONFormatElements ( $$result ) ]
2) Create a record (temporarily allow a protected field)
Execute FileMaker Data API [ Select ; Target: $$result ;
JSONSetElement ( “{}” ;
[ “action” ; “create” ; JSONString ] ;
[ “layouts” ; “Customers_edapi” ; JSONString ] ;
[ “fieldData” ;
“{ \”CustomerID\”:\”CUST-10027\” , \”Name\”:\”Acme Corp\” , \”Status\”:\”Active\” }” ;
JSONObject
] ;
[ “options” ; “{ \”prohibitmode\”:\”script\” , \”entrymode\”:\”user\” }” ; JSONObject ]
)
]
3) Update with optimistic concurrency (modId)
Execute FileMaker Data API [ Select ; Target: $$result ;
JSONSetElement ( “{}” ;
[ “action” ; “update” ; JSONString ] ;
[ “layouts” ; “Customers_edapi” ; JSONString ] ;
[ “recordId” ; $recordId ; JSONString ] ;
[ “modId” ; $expectedModId ; JSONString ] ;
[ “fieldData” ; “{ \”Status\”:\”Inactive\” }” ; JSONObject ]
)
]
If [ Get ( LastError ) = 0 ]
# success
Else If [ Get ( LastError ) = 301 ]
# record modified by another user; refetch and retry
End If
4) Create parent and related rows with portalData
Requires a layout with a portal where Allow creation of records is enabled for that table occurrence.
Execute FileMaker Data API [ Select ; Target: $$result ;
JSONSetElement ( “{}” ;
[ “action” ; “create” ; JSONString ] ;
[ “layouts” ; “Orders_withLines_edapi” ; JSONString ] ;
[ “fieldData” ; “{ \”CustomerID\”:\”CUST-10027\” , \”OrderDate\”:\”2/10/2025\” }” ; JSONObject ] ;
[ “portalData” ;
“{ \”Order_OrderLines\” : [
{ \”OrderLines::SKU\”:\”SKU-001\” , \”OrderLines::Qty\”:2 },
{ \”OrderLines::SKU\”:\”SKU-002\” , \”OrderLines::Qty\”:1 }
] }” ;
JSONObject
]
)
]
5) Duplicate and delete
// Duplicate
Execute FileMaker Data API [ Select ; Target: $$dup ;
JSONSetElement ( “{}” ;
[ “action” ; “duplicate” ; JSONString ] ;
[ “layouts” ; “Orders_edapi” ; JSONString ] ;
[ “recordId” ; $recordId ; JSONString ]
)
]
// Delete
Execute FileMaker Data API [ Select ; Target: $$del ;
JSONSetElement ( “{}” ;
[ “action” ; “delete” ; JSONString ] ;
[ “layouts” ; “Orders_edapi” ; JSONString ] ;
[ “recordId” ; $recordId ; JSONString ]
)
]
6) Discover structure with metaData
// List all table occurrences
Execute FileMaker Data API [ Select ; Target: $$tables ;
JSONSetElement ( “{}” ;
[ “action” ; “metaData” ; JSONString ] ;
[ “tables” ; “” ; JSONString ]
)
]
Set Variable [ $$tables ; JSONFormatElements ( $$tables ) ]
// List fields for a specific TO
Execute FileMaker Data API [ Select ; Target: $$fields ;
JSONSetElement ( “{}” ;
[ “action” ; “metaData” ; JSONString ] ;
[ “tables” ; “Orders” ; JSONString ]
)
]
Set Variable [ $$fields ; JSONFormatElements ( $$fields ) ]