Abandonment's `phone` discrepancy beteween REST and GraphQL

Hi everyone,

We’ve encountered a discrepancy between the REST and GraphQL APIs regarding abandonment creation for existing customers.

When user creates an abandonment for their existing customer in store (matched by email), and they check SMS marketing consent and provide a phone number:

  1. In the REST API, the phone field is populated as expected.
  2. In the GraphQL API, we can’t find any field that contains the phone number provided for SMS marketing consent.

We do need access to the phone number that was filled in during this process. Has anyone else run into this issue? Are we missing something in the GraphQL API, or is this a known limitation?

Any advice or workarounds would be greatly appreciated!
Thanks in advance for your help!

Requests for reference:

curl -X POST -H 'Content-Type: application/json' -H 'X-Shopify-Access-Token: ...' https://....myshopify.com/admin/api/2025-04/graphql.json -d '{"query": "query abandonedCheckouts($query: String!) {abandonedCheckouts(first: 250 query: $query) { nodes { id shippingAddress { phone} customer { phone id smsMarketingConsent { marketingState consentUpdatedAt } } }}}","variables":{"query":"updated_at:>=2025-05-11T23:16:07.829Z"}}' | jq '.data.abandonedCheckouts.nodes | map(select(.id == "gid://shopify/AbandonedCheckout/38820596384032"))[0]'
{
 "id": "gid://shopify/AbandonedCheckout/38820596384032",
 "shippingAddress": null,
 "customer": {
   "phone": null,
   "id": "gid://shopify/Customer/8944781590816",
   "smsMarketingConsent": null
 }
}
curl -H 'X-Shopify-Access-Token: ...' https://....myshopify.com/admin/api/2025-04/checkouts.json?updated_at_min=2025-05-11T23:16:07.829Z | jq '.checkouts | map(select(.id == 38820596384032))[0].phone'
"+14044111112"

With graphQL, we use CustomerPhoneNumber - GraphQL Admin and check marketingState

If you are checking SMS marketing status with GraphQL on a existing customer then this should work.

Also,

“smsMarketingConsent” is Deprecated.

smsMarketingConsent
•
CustomerSmsMarketingConsentState
Deprecated
Use defaultPhoneNumber.marketingState, defaultPhoneNumber.marketingOptInLevel, defaultPhoneNumber.marketingUpdatedAt, defaultPhoneNumber.marketingCollectedFrom, and defaultPhoneNumber.sourceLocation instead.

Unfortunatelly, it doesn’t have abandoned checkout’s phone.
I understand for security mesures customers’ data isn’t updated by creation of abandonment, get updated likely only by creation of order after paying for it.
That’s why we can’t use customer’s data for this scenario.

curl -X POST -H 'Content-Type: application/json' -H 'X-Shopify-Access-Token: ...' https://....myshopify.com/admin/api/2025-04/graphql.json -d '{"query": "query abandonedCheckouts($query: String!) {abandonedCheckouts(first: 250 query: $query) { nodes { id shippingAddress { phone} customer { phone id smsMarketingConsent { marketingState consentUpdatedAt } defaultPhoneNumber { marketingCollectedFrom marketingOptInLevel marketingState marketingUpdatedAt phoneNumber } } }}}","variables":{"query":"updated_at:>=2025-05-11T23:16:07.829Z"}}' | jq '.data.abandonedCheckouts.nodes | map(select(.id == "gid://shopify/AbandonedCheckout/38820596384032"))[0]'
{
  "id": "gid://shopify/AbandonedCheckout/38820596384032",
  "shippingAddress": null,
  "customer": {
    "phone": null,
    "id": "gid://shopify/Customer/8944781590816",
    "smsMarketingConsent": null,
    "defaultPhoneNumber": null
  }
}

Hey @SviatoslavSafronov :waving_hand: - is your app a public app (or a draft public app) by any chance? I can’t say for sure what the issue is here definitively, but I’m wondering if you are using a public app and if so, have you requested access to private customer data? That’s the common reason for phone numbers, etc to be nullified. More info here: Work with protected customer data

If you do have access to the protected data though, just let me know and I can do some more digging on my end here for sure. Hope this helps!

It’s development app created in the store.
The thing is that if it’s a new customer, their info is present in shippingAddress.