Mutations write data through the GraphQL API. Every table in the Data Model generates a fixed set of mutations automatically — you don’t write resolvers or input types by hand. The examples assume aDocumentation Index
Fetch the complete documentation index at: https://archie.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
students table with fields like firstName, lastName, email, age, and a city relationship.
Auto-generated mutations per table
For each table, Archie generates:| Mutation | What it does |
|---|---|
create<TableName> | Insert a single record. |
create<TableName>Many | Insert multiple records in one request. |
update<TableName> | Update a single record by id. |
delete<TableName> | Delete a single record by id. |
delete<TableName>Many | Delete multiple records by id. |
upsert<TableName> | Insert or update by a unique field — atomic. Generated for tables with at least one unique column. |

Single record mutations
Create
input object’s shape comes directly from the table’s schema. Mandatory fields without a default must be present; optional fields can be omitted.
Update
update is a partial update — only the fields in input change. Everything else stays as it was.
Delete
true on success.
Multiple record mutations
Create many
createStudentsMany runs as a single transaction. If any record fails validation, none are inserted.
For larger or dynamic batches, pass the inputs as a variable so you can reuse the operation:
Delete many
Nested mutations
Instead of pre-creating related records and passing their foreign keys, you can express the entire graph in one operation. Every relationship field accepts one of:create— insert a new related record inline.connect— link to an existing record by a unique field.connectOrCreate— find by a unique field; create if missing.
Atomic upserts
Tables with at least one unique column get anupsert<TableName> mutation. Pass a where clause that targets the unique column, plus create and update payloads. Archie atomically checks if the record exists and runs the matching branch.
upsert instead of “select then insert or update” — it eliminates the race condition between the two queries.
Permissions
Every mutation is checked against the per-role permissions in Role-Based Access. A user without write access to a table will receive an authorization error before the mutation runs. Field-level write rules apply too — fields a role isn’t allowed to write are rejected even if the rest of the input is valid.FAQ
What's the difference between `update` and `upsert`?
What's the difference between `update` and `upsert`?
update requires the record to exist and is keyed by id. upsert is keyed by any unique column and creates the record if it doesn’t exist. Use upsert when you have an external identifier (an email, a Stripe customer ID) and you don’t know whether the record already exists.Can I update related records in the same mutation?
Can I update related records in the same mutation?
What happens if the input is missing a mandatory field?
What happens if the input is missing a mandatory field?
The mutation fails before any data is written, with an error indicating which field is missing. The error includes the field name and the constraint that was violated.
Are bulk operations faster than looping individual mutations?
Are bulk operations faster than looping individual mutations?
Yes.
createStudentsMany runs in one round-trip and one transaction; a client-side loop runs one round-trip per record and serializes them. Use bulk for any batch over a few records.Can I get the inserted ids back from a bulk create?
Can I get the inserted ids back from a bulk create?
The default
createXxxMany mutation returns success. Project a richer payload by selecting more fields in the response if your bulk mutation supports it, or run a follow-up query keyed on the unique values you inserted.