Skip to main content

Connect + Shopify (Oct 2026): Look Up Orders Inside 8 Seconds

Cloud ArchitecturePalaniappan P13 min read

Quick summary: As of October 27, 2026, a Connect flow can wait at most 8 seconds for a synchronous Lambda, and Shopify caps one GraphQL query at 1,000 points. Here is a phone and order-number lookup that fits both, with a tested fallback.

Key Takeaways

  • As of October 27, 2026, a Connect flow can wait at most 8 seconds for a synchronous Lambda, and Shopify caps one GraphQL query at 1,000 points
  • As of October 27, 2026, the hard limit in a Connect flow that calls Shopify is 8 seconds
  • That is the maximum timeout on a synchronous Invoke AWS Lambda function block
  • Shopify's side has its own ceiling: a single GraphQL query can cost at most 1,000 points, and a Standard plan restores 100 points per second
  • A Connect flow passes the caller's phone number or a spoken order number to a Lambda
Typographic data card titled Shopify lookup, 8 s budget, listing five limits: 8 second synchronous Lambda timeout in a Connect flow, 64 KB Lambda response, 32,768 bytes of contact attributes, Shopify 1,000 point maximum query cost, and a Standard plan restore rate of 100 points per second. Not a product screenshot.
Table of Contents

As of October 27, 2026, the hard limit in a Connect flow that calls Shopify is 8 seconds. That is the maximum timeout on a synchronous Invoke AWS Lambda function block. Shopify’s side has its own ceiling: a single GraphQL query can cost at most 1,000 points, and a Standard plan restores 100 points per second. A lookup that fits both is small: one customer, their latest order, one fulfillment.

This post builds that lookup. A Connect flow passes the caller’s phone number or a spoken order number to a Lambda. The Lambda queries the Shopify Admin GraphQL API under a hard timeout and returns a flat map of strings. If Shopify is slow, throttled, or wrong, the flow gets a safe answer instead of silence.

Every capability is labeled. Native means built into Connect or AWS. Supported integration means a connector AWS documents. Custom engineering means code you write and run. The Lambda handler and its test are in the artifact folder. The wider eCommerce picture is on Amazon Connect for eCommerce and the Shopify and Bedrock side is in Shopify on AWS and Bedrock + Shopify.

Modeled design (not a cited client): FactualMinds has no published Connect plus Shopify engagement. The numbers below are AWS and Shopify documented limits and arithmetic on published prices. The one measurement is the mocked timeout test in the artifact, which shows the fallback returns in about 50 ms against a 50 ms budget. It does not measure Shopify.


Architecture and what is native

PieceLabelRole
Invoke AWS Lambda function blockNative (Connect)Sync call, max 8 s, STRING_MAP response validation
Lambda handlerCustom engineeringParse event, query Shopify, return flat map
Shopify Admin GraphQL APIVendor APICustomer and order data
Secrets ManagerNative (AWS)Holds the Shopify credential
Customer Profiles Shopify connectorSupported integration (AWS docs)Optional cache of customers and orders
Shopify webhooks to EventBridgeVendor feature + custom rulesOptional change events
Agent workspace Detail viewNative (Connect)Shows attributes to the agent

The live path is flow, Lambda, Shopify, back. The optional second path is Shopify, webhooks, Customer Profiles, so a profile already exists when the call lands. You can run either path or both. Most teams need only the first on day one.

Start with the live lookup. It is one function, one secret, and no sync job to debug. Add Customer Profiles when the agent needs history across contacts, not when you only need “where is my order”.


Shopify access: what changed and what to use

Shopify’s current model, from its developer docs:

  • Dev Dashboard apps get a token through the client credentials grant. You POST grant_type=client_credentials, client_id and client_secret to https://{shop}.myshopify.com/admin/oauth/access_token. Do not send a scope. Shopify says it ignores it. The token carries the scopes the store granted to your installation, and expires_in is always 86399 seconds (24 hours).
  • The grant works only when the app and the store are in the same Shopify organization. For a store outside it, such as a client’s store, Shopify points to custom distribution with token exchange or the authorization code grant.
  • Legacy custom apps created in the store admin: Shopify staff stated on the developer community forum that new legacy custom apps cannot be created from January 1, 2026, and that existing ones keep working. We read that as a community post, not a Shopify docs page, so confirm in your store admin before you plan around it.

The AWS Shopify connector page for Customer Profiles still describes the older authorization-code flow with an API version of 2021-04 in its webhook example. That page predates the Dev Dashboard model. Treat its steps as the shape of the work, not as the current click path.

Request the minimum scopes:

ScopeWhyCatch
read_ordersOrder name, financial and fulfillment statusOrders from the last 60 days only
read_all_ordersOrders older than 60 daysDeclared alongside read_orders. Partner-organization apps request it in the Partner Dashboard. Apps under a merchant organization in the Dev Dashboard do not need Shopify approval
read_customersLook up a customer by phoneCustomer name, email and phone are protected customer data

By default apps have no access to protected customer data. You can declare scopes early, but on a non-development store the API will not return that data until Shopify approves your app. Start the approval request before you plan a go-live date.

Put the credential in Secrets Manager and give the Lambda role secretsmanager:GetSecretValue on that one secret ARN. The artifact reads a JSON secret with either accessToken or clientId and clientSecret. With client credentials it caches the 24-hour token in module scope and refreshes it a minute before expiry. Never put the token in a Lambda environment variable or in a contact attribute.


The Lambda contract with Connect

Verified against the Connect admin guide:

  • The response is a flat object of string key and value pairs when response validation is STRING_MAP. JSON allows nesting. Arrays cannot be referenced in a flow.
  • Size is under 64 KB of UTF-8. The admin guide says values include only alphanumeric, dash and underscore characters. We did not test whether the service rejects other characters. The artifact sanitizes to that set, so O'Neil becomes O-Neil.
  • A synchronous block times out at 8 seconds. The Error branch fires on a timeout, a thrown exception, or a response Connect cannot parse.
  • On a sync error Connect retries up to 3 times within the 8 seconds. A function that throws on a Shopify 500 can use most of the budget on retries.
  • Total contact attributes are capped at 32,768 UTF-8 bytes. A chain of Lambdas is limited to 20 seconds in total.

The handler never throws. It catches everything and returns {found: "false", lookupStatus: "timeout"} and similar. The statuses are ok, not_found, ambiguous, no_identifier, timeout, throttled, auth, not_configured and error. The flow routes on lookupStatus, so “we could not check” is never spoken as “you have no order”. A revoked token returns auth, not not_found, for the same reason.

The one time budget covers the token fetch as well as the query: the Secrets Manager read and the OAuth call both receive the same abort signal.

The input is the standard Connect event. The caller’s number is Details.ContactData.CustomerEndpoint.Address, and any flow parameter arrives under Details.Parameters. Sample events are in the artifact folder.


Customer and order lookup

Context: Admin GraphQL API version 2026-10 (the version label on Shopify’s reference at the time of writing). Pin the version in an environment variable and re-test when you change it.

By phone, returning the customer’s latest order. This is the query the artifact sends. It asks for two customers on purpose: if two share the number, the handler returns ambiguous instead of reading out whichever one Shopify listed first.

query($q: String!) {
  customers(first: 2, query: $q) {
    nodes {
      firstName
      orders(first: 1, sortKey: PROCESSED_AT, reverse: true) {
        nodes { ...O }
      }
    }
  }
}
fragment O on Order {
  name
  displayFinancialStatus
  displayFulfillmentStatus
  fulfillments(first: 1) { trackingInfo(first: 1) { company } }
}

Variables: {"q": "phone:+15555550100"}. Shopify’s customers reference lists phone and email as searchable filters and notes that email is a tokenized field, so quote an exact address as a phrase. Connect gives you E.164 for a caller, so the handler rejects anything else without calling Shopify.

By order number, from a prompt the caller answered:

query($q: String!) {
  orders(first: 1, query: $q) {
    nodes { ...O customer { firstName } }
  }
}

Variables: {"q": "name:#1001"}. The handler strips everything except letters, digits and dashes from the spoken value before it builds the filter.

What we verified and what we did not: from Shopify’s reference pages we confirmed Order.name, displayFinancialStatus, displayFulfillmentStatus, fulfillments(first), Order.customer, and Fulfillment.trackingInfo. We confirmed the orders query takes query, first, sortKey and reverse. We could not confirm from the pages we read the Customer.orders arguments, Customer.firstName, the sub-fields of FulfillmentTrackingInfo, or the exact enum spellings. Run both queries in your store’s GraphiQL before you trust the artifact. The test uses a mocked response and cannot catch a wrong field name.


Rate limits

Shopify’s GraphQL Admin limits, from its rate-limits page:

LimitValue
Max cost of a single query1,000 points
Restore rate, Standard100 points per second
Advanced200
Shopify Plus1,000
Commerce Components2,000
Array input argumentsmax 250 items
Paginationpaginated arrays cap at 25,000 objects

Cost is calculated from the fields you request, before and after execution. Objects cost 1, scalars and enums cost 0, mutations cost 10. Every response carries extensions.cost.throttleStatus with maximumAvailable, currentlyAvailable and restoreRate. The page does not state a bucket size for each plan, so read it from a live response instead of assuming one.

Our lookup asks for one customer, one order and one fulfillment. We did not calculate its point cost. Read requestedQueryCost from a real response and write it down. If a store on the Standard plan takes bursts of calls after a marketing email, the 100 per second restore rate is the number to divide by. Shopify’s backoff guidance is to wait at least one second after a throttle. In an 8-second flow that means one retry at most, so the handler does not retry. It returns throttled and the flow falls back.

Two throttle signals exist in what we read: a 429 response and the cost block. A GraphQL throttle can also arrive as HTTP 200 with an errors array. The handler maps HTTP 429, and any error whose extensions.code is THROTTLED, to throttled; every other errors array becomes error. We did not confirm THROTTLED against a live overflow, so check the code your API version returns.


Customer Profiles: cache or 360 layer

Customer Profiles has a Shopify connector. AWS documents it as a featured application using Amazon AppIntegrations. The steps:

  1. In the Connect console, Customer profiles, Add integration, choose Shopify.
  2. Create the connection. It needs your Shopify Partner app URL and the source name of an EventBridge event source created in the Partner dashboard.
  3. Pick object types for ingestion. Ingestion starts with records created after the integration is added. For history, AWS says to use Amazon S3 as a source.
  4. Create webhook subscriptions yourself. The documented topics are customers/create, customers/enable, customers/update, draft_orders/create, draft_orders/update, orders/cancelled, orders/create, orders/fulfilled, orders/paid, orders/partially_fulfilled and orders/updated.

The scopes AWS lists are read_customers, read_orders and read_draft_orders. AWS says the connector needs a customer managed KMS key. We did not verify which Regions support the Shopify connector today. The 2022 launch post lists 8 Regions, so check the current availability page.

The connector is a supported integration. A flow that reads the profile is native. A custom ingestion with AppFlow or the Customer Profiles API is custom engineering. We found no AppFlow Shopify connector in the sources we read, so we would not plan around one.

Live versus cached:

Live Lambda lookupCustomer Profiles cache
FreshnessCurrent at call timeAs of the last event delivered
Failure modeTimeout, throttle on the callSilent staleness, no health signal
Extra setupOne Lambda, one secretPartner app, event source, subscriptions, KMS key
Cost shapePer callProfile and ingestion charges (not quoted here)
Best forOrder status in a flowAgent history across contacts

AWS’s page says Last run and Integration health are not available for this integration type, and that if the connection stops you delete and re-establish it. Plan a daily check: create a test customer in Shopify and confirm the profile appears. That check is exactly the one AWS’s verify step uses.

Use live lookup for the IVR and chat order-status question. Use the profile for the agent screen. The cost is two sources that can disagree. When they do, trust the live lookup.


Webhooks

Shopify delivers webhooks over HTTPS or to Amazon EventBridge. The EventBridge route in Shopify’s docs creates an event source for your AWS account ID and Region in the dashboard, you associate it with an event bus, and rules route to Lambda or SQS. The subscription URI has the form arn:aws:events:<REGION>::event-source/aws.partner/shopify.com/<APP-ID>/<SOURCE-NAME>. We did not verify Region coverage.

Use HTTPS delivery only if you need your own endpoint. Then verify the X-Shopify-Hmac-SHA256 header, a base64 HMAC-SHA256 of the raw request body with your client secret. Verify before any JSON parsing. Respond 200 fast. Shopify has a one-second connection timeout and a five-second timeout for the whole request, retries 8 times over 4 hours, and deletes an Admin API subscription after 8 consecutive failures. Dedupe on X-Shopify-Webhook-Id.


Agent workspace: show the order to the agent

Keep this short. Set the Lambda results as contact attributes with a Set contact attributes block, then show them in the agent workspace. A step-by-step guide with an AWS managed Detail view can display attributes when the contact starts. Its AttributeBar takes a label and value per item. For the legacy CCP, a screen pop needs the Streams API and a custom application.

Show lastOrderName, lastOrderStatus, fulfillmentStatus and carrier. Do not show anything the agent does not need. The deeper build is in custom agent UI and Customer Profiles.


Security and PII

  • Least privilege: read_orders and read_customers only. No write scopes. Add read_all_orders only if agents really need orders older than 60 days.
  • Minimize attributes: attributes are stored with the contact and counted against 32,768 bytes. The artifact returns the first name only, an order name, two statuses and a carrier. It does not return email, address, phone or line items.
  • Do not log the response: the handler writes one JSON line per call with lookupStatus, duration, and the HTTP status or GraphQL error codes on failure. It never logs the query variables or the data. Add the request cost from extensions.cost if you track it. Because the handler never throws, Lambda’s Errors metric stays at zero: alarm on a CloudWatch metric filter over lookupStatus instead.
  • The caller ID is not authentication, and neither is an order number (see the FAQ). The artifact does not verify identity; add a second-factor check in the flow before reading anything out.
  • Shared responsibility: using Secrets Manager and Connect does not make a design compliant on its own. Your PII and retention rules still apply to attributes and recordings.

What broke

What broke: modeled, not a cited client. The flow’s Lambda block has an 8-second timeout. The first version of a handler threw on any non-200 from Shopify. Connect retries a thrown error up to 3 times inside the 8 seconds. A Shopify 500 or a throttle then consumes the window with retries and the caller hears silence before the Error branch. Detection: a flow test where the mock returns 500. Fix: catch everything, return lookupStatus: error immediately, and route that to a message that offers an agent. The artifact test covers 429, 500, GraphQL errors, no-match and a hung request. The second trap is spoken as truth: found = false after a timeout reads as “no order”. Route on lookupStatus.

Reproduce this: Run node --test in the Shopify artifact folder. It mocks fetch and checks the flat string map, the query variables, each fallback status including ambiguous and auth, that a hung query or a hung token fetch aborts at the budget and returns instead of throwing, and that the log line never contains the phone number. It does not call Shopify.


Deployment validation

  1. Unit: node --test passes.
  2. GraphiQL: run both queries against a development store. Record requestedQueryCost and throttleStatus.
  3. Lambda test event: invoke with the sample event and with a bad phone. Confirm a flat string map both times.
  4. Flow test: use Connect’s testing and simulation, which as of October 26, 2026 also validates the data a Lambda action returns. See the evaluation checks post for that launch. Test the Error branch by pointing the secret at a bad token.
  5. Test call: call from a number on a test customer. Then from a number with no customer. Then block egress to Shopify and confirm the fallback message within the timeout.
  6. Rollback: keep the previous flow version published. If the lookup misbehaves, remove the Lambda block from the entry flow, not the function. Rotating the secret is the fix for a leaked token.

Troubleshooting:

SymptomCheck
Always not_foundPhone stored without +, or protected customer data not approved
error on every callToken expired, scope missing, wrong API version, GraphQL field renamed
timeout under loadThrottle or slow API. Read throttleStatus, lower field count
Error branch fires, no fallbackHandler threw. Check CloudWatch for an uncaught exception or a response over 64 KB
Profile missing in the agent viewEventBridge event source not Active, or subscription deleted after failures

Costs (published prices, checked October 27, 2026)

  • Connect voice: the Connect pricing page lists $0.038 per voice minute and $0.010 per chat message. It says pricing varies by region and communication type, and did not break out phone number or Customer Profiles charges on that page.
  • Lambda, US East (N. Virginia): $0.20 per 1M requests and $0.0000166667 per GB-second, with a free tier of 1M requests and 400,000 GB-seconds a month.

Arithmetic, not a measurement: 100,000 lookups a month at 512 MB and 1 second each is 50,000 GB-seconds. That is about $0.83 of compute plus $0.02 of requests at list price before the free tier. The Connect minutes the callers already use cost far more than the lookup.


What to do this week

  1. Decide which identifier you will trust: the order number the caller says, not the caller ID alone.
  2. Create a development store and a Dev Dashboard app with read_orders and read_customers. Start the protected customer data request.
  3. Run both GraphQL queries in GraphiQL and record requestedQueryCost.
  4. Deploy the artifact handler with a 4.5 s budget under a 6 s function timeout and a 7 s flow block timeout.
  5. Route the flow on lookupStatus. Write the timeout message before the happy-path message.
  6. Test the 429 and 500 paths with the mock, then with a bad secret in the dev store.

FactualMinds is an AWS Select Tier Services Partner. If you want this wired into your flows end to end, start at Amazon Connect consulting or contact us.


What this post doesn’t cover

  • Live Shopify measurements: no latency, query cost, or deflection numbers. We did not run against a store.
  • BigCommerce and WooCommerce: see the BigCommerce and WooCommerce post.
  • Writes: cancelling, refunding or editing an order from a flow. That needs write scopes and a separate risk review.
  • Connect AI agents answering order questions: see Connect AI agents for FAQ and self-service.
  • Pricing for Customer Profiles, telephony and AppIntegrations: use the current price pages for your Region.
  • Shopify Plus checkout and B2B specifics, and Shopify’s Region coverage for EventBridge.

Frequently asked questions

Does Amazon Connect have a native Shopify integration?
Partly. Customer Profiles has a Shopify connector in the AWS admin guide. It ingests customer, draft order and order events through Amazon AppIntegrations and an Amazon EventBridge partner event source, and it needs a Shopify Partner app. It does not run a live lookup from a flow. For a live order status in an IVR or chat flow you write a Lambda and call the Shopify Admin API yourself. That part is custom engineering.
How long can a Connect flow wait for the Shopify lookup?
A synchronous Invoke AWS Lambda function block accepts a timeout of at most 8 seconds. After that the contact goes down the Error branch. On an error Connect retries up to three times within that window, so a function that throws can burn the whole budget. Return a fallback map instead of throwing.
Which Shopify scopes does an order lookup need?
read_orders and read_customers. read_orders covers orders from the last 60 days. Older orders also need read_all_orders. Customer name, email and phone are protected customer data. On a non-development store the API will not return them until Shopify approves the app for protected customer data.
Can I use the client credentials grant for a client's store?
Only if the app and the store belong to the same Shopify organization. Shopify states that client credentials cannot reach a store outside your organization. For a merchant's own store that you do not own, Shopify points to custom distribution with token exchange or the authorization code grant.
When should we not call Shopify live from the flow?
Skip the live call when the caller is verified by something other than phone, when the contact volume could exceed your plan's restore rate, or when you only need to greet the caller by name. Use a cached Customer Profiles record, or no lookup at all, and let the agent query after answer. A live call also adds a failure path to every contact.
What could go wrong with phone-number matching?
The caller ID is not an identity. A shared household line can match two customers (the artifact returns `ambiguous` rather than picking one), a customer with no phone on file returns nothing, and a spoofed number returns a real order. Treat the result as context for the agent, not as authentication. Do not read order details to the caller until they confirm a second factor, such as the email or billing postcode on the order. An order number alone is weak proof: it is printed on confirmation emails and packing slips.
Is the order status stale if I use Customer Profiles?
It can be. AWS's Shopify connector page says events are near real time and that Last run and Integration health are not available for this integration type. If it stops working, AWS says to delete and re-establish the integration. A live lookup is current at call time. A profile is current as of the last event that arrived.
Does this post prove a result for our store?
No. The artifact test mocks fetch and proves the response shape and the timeout fallback. It does not call Shopify, so field names must still be checked in your store's GraphiQL. We have no published Connect plus Shopify engagement and report no latency or deflection numbers.
Palaniappan P
Palaniappan P

AWS Cloud Architect & AI Expert

AWS-certified cloud architect and AI expert with deep expertise in cloud migrations, cost optimization, and generative AI on AWS.

AWS ArchitectureCloud MigrationGenAI on AWSCost OptimizationDevOps

Recommended Reading

Explore All Articles »