Blog • AI / App Intents

After iOS 27 Opens More Siri Actions, How Does App Action JSON Actually Flow? From the Spoken Request to the API Call

A Siri request runs because it first becomes App Intent parameters, then AppIntent decides inside perform() whether to stay on device or call your API. The system does not forward the raw utterance to your server.

Whether Siri counts as an agent is in the previous article. This one follows a single request: how a phrase selects an Intent, how parameters become JSON, and why the API runs only after validation.

Hold this first: Speech is not the request body. The filled Intent parameters are. The sections below follow phrase, parameter type, entity id, your JSON, then the API.

Five steps in one request

The official entry is App Intents. See Getting started with App Intents. Siri, Shortcuts, and an in-app button share one Intent. They differ in who fills the parameters.

  1. 1
    Match the phrase

    You register spoken phrases on AppShortcutsProvider. The system uses that phrase to select an Intent. It does not hand the raw sentence to a model to improvise.

  2. 2
    Fill parameters

    Each @Parameter on the Intent tells the system which value it needs and whether it is required. A missing value prompts the person. It does not guess and send.

  3. 3
    Resolve the entity

    User data is resolved through EntityQuery by id. The parameter holds the entity, not a paragraph that describes it.

  4. 4
    Run

    perform() is where you read values that are already resolved. If the device can finish the action, finish it there.

  5. 5
    Answer Siri

    Return the outcome with IntentResult or a dialog. A failure still needs a sentence a person can hear. Do not leave the error only in a server log.

Three kinds of parameters

Parameter types are covered in Adding parameters to an app intent. Pick the wrong type and the JSON downstream will not stay stable.

TypeUse it forIn JSON
String, number, dateSimple input such as a quantity or a noteCopy it into parameters as-is
AppEnumA set fixed at compile time, such as pickup versus deliveryStore the enum value. Do not use the display string as the key
AppEntityUser data that changes, such as one productStore only the resolved id

A fixed set is an AppEnum. A list the person can add to or delete is an AppEntity plus a query. If you model a changing list as an enum, phrases stop matching as soon as an option expires.

An entity keeps only its id

The system needs an entity it can display and query. Your database remains the source of the data. The entity needs at least a stable id and a name a person can read.

The entity fields you can record after resolution. The id is the key the API uses later.
{
  "entity": "OrderItem",
  "id": "sku_42",
  "display": "Oat milk"
}

Implement entities(for identifiers:) and load the object by id. If it is missing, do not invent an id and continue.

The parameter JSON you own

The document below is the contract you persist inside perform() before you decide whether to call the API. It is not Apple's request format, and the system will not read the file for you.

One resolved order request. resolved is true only after the entity query succeeds.
{
  "intent": "StartOrder",
  "source": "siri",
  "parameters": {
    "item_id": "sku_42",
    "quantity": 1
  },
  "resolved": true
}

When to call the API

  1. 1
    Finish on device

    An action that only changes local state finishes inside perform(). It does not need the network.

  2. 2
    Validate first

    When you need a server, validate the JSON with a schema first. A missing item_id or a quantity below 1 stops on the device.

  3. 3
    Then go to the network

    Send parameters to your API only after validation passes and resolved is true. The server looks up its own record by id. It does not trust the display name.

  4. 4
    Say the failure in plain language

    If the API rejects the call or times out, tell the person through the Intent dialog that it did not finish. Do not let Siri say it succeeded.

How a third-party app declares the Intent and returns a failure is the next article. This one stops at the data path.

How this differs from older articles

Is Siri an agent?This article
QuestionWhether the system plans and calls tools on its ownWhich JSON a single request passes through on the way to an API
Do not look here forAnother product announcementTreating the raw utterance as a request body you can store

The product story of the hardware and system features is in why iPhone 18 is more than hardware. That piece does not split parameter fields.

Check this JSON in JSONNote

  1. 1
    Format

    Open the parameter record in JSON format and confirm there is no trailing comma.

  2. 2
    Catch missing fields with a schema

    Paste the schema below into JSON Schema. A missing intent or item_id, or a quantity that is not a positive integer, should not be sent to the API.

  3. 3
    Then check one sample

    Paste a real sample into JSON validate. Look especially at whether item_id is an empty string.

JSON Schema for the parameter record. source allows only siri, shortcut, and app.
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "additionalProperties": false,
  "required": ["intent", "source", "parameters", "resolved"],
  "properties": {
    "intent": { "type": "string", "minLength": 1 },
    "source": { "enum": ["siri", "shortcut", "app"] },
    "resolved": { "type": "boolean" },
    "parameters": {
      "type": "object",
      "required": ["item_id", "quantity"],
      "properties": {
        "item_id": { "type": "string", "minLength": 1 },
        "quantity": { "type": "integer", "minimum": 1 }
      }
    }
  }
}

FAQ

Does the system send the whole utterance to my server?

Not on this path. The server should receive the parameter JSON you assemble and validate inside perform(). Speech stays in on-device recognition.

Why not put the product name in the parameters?

Names change and collide. An AppEntity uses a stable id, and the query loads the object by that id. The API should accept the id only.

If the schema passes, can I call the API?

Also check resolved. A valid shape with an unresolved entity means the person has not picked an object yet. Calling the API then turns a follow-up question into a wrong order.

How do you split on-device work from a network call?

Changes that stay on device finish inside perform(). Work that needs your backend writes the parameter JSON, validates it, then requests. Both paths return the outcome through IntentResult.

Is a Shortcut with hand-filled parameters the same path?

Yes, it is the same AppIntent. The difference is who fills the parameters: Siri uses the phrase, Shortcuts uses the person or the previous action. Entity resolution, JSON, and the API gate stay the same.

Conclusion

The data path of one request is: a phrase selects an Intent, parameters are filled by type, the entity collapses to an id, you write JSON, the API runs only after validation, and a dialog returns the outcome to Siri.

Direct conclusion: do not upload the raw utterance. Do not call the API before the id is resolved. Say a failure back to the person instead of leaving it only in a server log.

Next: lock this parameter JSON with a schema before you wire it into perform().

Back to the blog