How to link a user account with an Instacart account
Learn how to link a Connect user account with an Instacart account. For background information, example user journeys, and concept diagrams, see Account linking.
Prerequisites
- Instacart has added the account linking scope to your Connect OAuth application.
- You have provided Instacart a redirect URI.
- Instacart has registered the redirect URI to your OAuth application.
- Instacart has provided you with the authorization URL.
- A billing reconciliation process is set up to handle delivery discounts.
For help with prerequisites, contact your Instacart representative.
Best practices
If you build your web application to offer account linking, consider following these best practices:
- Manage account linking from the customer’s account profile page.
- Market the advantage of using an Instacart+ membership. For example, you might add Instacart+ Member? Link your account to receive $0 delivery or similar text to your checkout flow.
- Verify the customer’s Instacart+ membership status when they sign in and when they checkout. Doing so enables you to inform customers of various incentives and check whether they are eligible for the delivery discount.
- Show customers who are Instacart+ members their delivery savings at checkout.
- Inform customers that they can unlink their accounts by contacting Instacart customer service.
Authorization URL
The authorization URL points to Instacart’s OAuth endpoint. It acts as the gateway for securely linking your platform user accounts to Instacart user accounts.
https://<instacart_auth_endpoint>?response_type=code&client_id=<your_Connect_OAuth_client_id>&scope=account_linking&state=<CSRF_prevention_token>&redirect_uri=https://example.org/account/profile
The authorization URL has the following query parameters:
response_type
: The type of response requested. Its value must becode
.client_id
: The ID of your Connect OAuth application.scope
: The access-level needed. Its value must beaccount_linking
.state
: A unique, random value generated by your server that is used to protect against cross-site request forgery (CSRF) attacks.redirect_uri
: The URL that you want Instacart to redirect customers to after they grant access to their account. Its value must match the URI registered to your Connect OAuth application.
After customers are authenticated, they’re prompted to either allow or deny your OAuth application’s account access request.
The following is an example of the authorization prompt when customers are logged into their Instacart account:
If customers grant access, Instacart sends them to your redirect_uri
, to which we append our authorization code
and your state
values as query parameters.
https://example.org/account/profile?code=<authorization_code>&state=<CSRF_prevention_token>
Components
On the front-end of your web application, implement a status element and an account linking results dialog window.
Status element
On the customer’s account profile page, which ideally has the same URL as your registered redirect URI, implement a dynamic UI element. The purpose of the element is to let customers manage their existing Instacart+ subscription, purchase a new subscription, or initiate the account linking process. Depending on the customer’s account status, you should display the element in one of the following states:
Linked accounts and an active Instacart+ subscription
- Content
- Example UI
- Informs customers that their retailer account is linked to their Instacart account, and that they have an active Instacart+ subscription.
- Displays the subscription’s expiration date as a reminder to customers.
- Contains a button whose click handler opens
https://www.instacart.com/store/account/instacart-plus
. On this page, customers can manage their Instacart+ subscription.
Linked accounts and an inactive Instacart+ subscription
- Content
- Example UI
- Informs customers that their retailer account is linked to their Instacart account, but they don’t have an active Instacart+ subscription.
- Contains a button whose click handler opens
https://www.instacart.com/signup?next=%2Fstore%2Faccount%2Finstacart-plus
. On this page, customers can create an Instacart account and purchase an Instacart+ subscription.
Unlinked accounts
- Content
- Example UI
- Informs customers that their retailer account is not linked to their Instacart account.
- Contains a link accounts button whose click handler opens the authorization URL.
- Contains a purchase membership button whose click handler opens
https://www.instacart.com/signup?next=%2Fstore%2Faccount%2Finstacart-plus
. On this page, customers can create an Instacart account and purchase an Instacart+ subscription.
Account linking results dialog window
On the same page that contains the status element, implement a set of dialog windows that display the results of the account linking process.
Account linking succeeded
- Content
- Example UI
- Informs customers their accounts are linked.
- Contains a button that redirects customers to your storefront.
Account linking failed
- Content
- Example UI
- Informs customers that the account linking process failed.
- Provides instructions on how to resolve the problem.
- Contains a button that closes the dialog or redirects to the account page.
Check for authorization
When the customer’s account profile page loads, parse the URL to determine whether it has code
and state
query parameters appended to it. If it doesn’t (which indicates that the customer hasn’t granted account access during the current session), then update the status element.
https://example.org/account/profile
If it does (which indicates that the customer has granted account access during the current session), then link the customer’s accounts.
https://example.org/account/profile?code=<authorization_code>&state=<CSRF_prevention_token>
Update the status element
To update the status element, pass the customer’s ID to your server and then include that value as a path parameter in a get account information request.
curl --location 'https://<instacart_connect_domain>/v2/fulfillment/users/1990ad78-9f7a-4302-95cb-f70fe03b6b04/link' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
If the response status code is 200
(which indicates that the customer has a Connect user account and it’s linked to their Instacart account) then check the value of instacartplus_member
. If it’s true
, get the value of expired_at
, convert it to a more human-readable format, such as MM/DD/YYYY, add that date to the linked and active status element and then display it to the customer. If it’s false
, display the status element as linked and inactive.
{
"express_member": true,
"instacartplus_member": true,
"expired_at": "2025-09-22T07:14:43Z"
}
If the response has a 400
status code, then the error.message
is either User Not Found
or User Not Linked
.
{
"error": {
"message": "User Not Linked",
"code": 1001
},
"meta": {
"key": "user_id"
}
}
In both cases, use a cryptographic library to create a random, unique CSRF prevention token and associate it with the user session. Provide the token to your front-end by embedding it in the HTML or including it in an API response.
On your front end, store the token in temporary memory. When handling link account button click events, assign the token to the authorization URL’s state
parameter.
Link customer accounts
To initiate the account linking process, send your redirect URI, the Instacart generated authorization code, and the CSRF token to your server. On the back end, get the session’s CSRF prevention token and determine whether the two values match. If they don’t match, signal to your front end to display the account linking failed dialog.
If they do, make a generate linking token request. When configuring the request, do the following:
- Set the
grant_type
toauthorization_code
. - Provide your OAuth application’s
client_id
andclient_secret
. - Assign the Instacart generated authorization code to
code
. - Assign the base URL to
redirect URI
so Instacart can check whether it’s valid.
curl --location 'https://<instacart_connect_domain>/v2/oauth/token' \
--header 'Content-Type: application/json' \
--data '{
"grant_type": "authorization_code",
"client_id": "<Oauth client id>",
"client_secret": "<Oauth client secret>",
"code": "<authorization code>",
"redirect_uri": "https://example.org/account/profile"
}'
If the response has a 400
or 401
status code, signal to the front-end to display the account linking failed dialog. Otherwise, get access_token
from the body and save the value.
{
"access_token": "<access_token>",
"token_type": "Bearer",
"expires_in": 86400,
"refresh_token": "<refresh_token>",
"scope": "account_linking",
"created_at": 1757025142
}
Next, configure the link user accounts request. Pass the saved access token to linking_token
and include the customer’s ID in the request path.
The Authorization
header must have a fulfillment access token.
curl --location 'https://<instacart_connect_domain>/v2/fulfillment/users/1990ad78-9f7a-4302-95cb-f70fe03b6b04/link' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"linking_token": "<access_token>"
}'
If the response status code is 200
or success
is true
in the body, then display your accounting linking succeeded dialog window.
{
"success": true
}
If the status code is 400
and the error.message
is User Not Found
, then assign the customer’s ID to user_id
in a create Connect user account request and, after receiving a successful response, retry the link accounts request.
Otherwise, display the account linking failed dialog.
Flow diagram
The following diagram shows the API calls, security checks, and UI updates that occur during an account linking flow: