Create a Connect user account
POST /v2/users
Creates the Connect user account that Carrot Ads requires before you can serve ads or send events. The user_id is defined by you and must be unique across the retailer's customers. For example, you might use a loyalty ID. The minimum required fields are user_id and first_name.
This path and Create a Connect user account (POST /v2/fulfillment/users) create the same Connect user account. The paths differ in rate limits and phone-number handling. If your site already uses Connect Fulfillment, reuse those user IDs instead of creating a second account.
Creation is synchronous. Create the user before you request ads or send events.
Security
| Name | In | Description |
|---|---|---|
Authorization | header | The Authorization header with the bearer token acquired during authentication. |
Parameters
The request accepts the X-Retailer-Id header. The retailer slug is required only for a retailer with multiple banners. For more information, see Identifiers.
Request
| Field | Type | Required | Description |
|---|---|---|---|
user_id | string | The ID of the user. | |
first_name | string | The user's first name. | |
last_name | string | The user's last name. | |
phone_number | string | The user's phone number. | |
locale | string | The user's locale in POSIX format. Example: en_US. | |
metadata | Hash | The user-level metadata. |
The request body uses the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
user_id | string | Required | Unique identifier for the customer, defined by you. |
first_name | string | Required | Customer's first name. Do not include /, :, <, >, $, %, or ?. |
last_name | string | Optional | Customer's last name. Same character restriction as first_name. |
phone_number | string | Optional | Phone number in E.164 format. For example, +14155552671. |
locale | string | Optional | Locale in POSIX format. For example, en_US. |
metadata | object | Optional | String key-value pairs associated with the user. Use only metadata fields agreed upon with Instacart. |
Request examples
Use your assigned Instacart domain. The generated examples use the Connect production host.
curl -i -X POST \
-H 'X-Retailer-Id: <retailer_slug>' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <token>' \
https://<instacart_domain>/v2/users \
-d '{"user_id": "kamalsingh1234", "first_name": "Kamal"}'
- cURL
- Java
- Python
- Go
curl --request POST \
--url https://connect.instacart.com/v2/users \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"user_id": "string",
"first_name": "string",
"last_name": "string",
"phone_number": "string",
"locale": "string",
"metadata": {
"key1": "value1",
"key2": "value2"
}
}'
HttpResponse<String> response = Unirest.post("https://connect.instacart.com/v2/users")
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.header("Authorization", "Bearer <token>")
.body("{\n \"user_id\": \"string\",\n \"first_name\": \"string\",\n \"last_name\": \"string\",\n \"phone_number\": \"string\",\n \"locale\": \"string\",\n \"metadata\": {\n \"key1\": \"value1\",\n \"key2\": \"value2\"\n }\n}")
.asString();
import http.client
conn = http.client.HTTPSConnection("connect.instacart.com")
payload = "{\n \"user_id\": \"string\",\n \"first_name\": \"string\",\n \"last_name\": \"string\",\n \"phone_number\": \"string\",\n \"locale\": \"string\",\n \"metadata\": {\n \"key1\": \"value1\",\n \"key2\": \"value2\"\n }\n}"
headers = {
'Accept': "application/json",
'Content-Type': "application/json",
'Authorization': "Bearer <token>"
}
conn.request("POST", "/v2/users", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://connect.instacart.com/v2/users"
payload := strings.NewReader("{\n \"user_id\": \"string\",\n \"first_name\": \"string\",\n \"last_name\": \"string\",\n \"phone_number\": \"string\",\n \"locale\": \"string\",\n \"metadata\": {\n \"key1\": \"value1\",\n \"key2\": \"value2\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Accept", "application/json")
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(res)
fmt.Println(string(body))
}
Response
| Field | Type | Required | Description |
|---|---|---|---|
user_id | string | The ID of the user. | |
first_name | string | The user's first name. | |
last_name | string | The user's last name. | |
phone_number | string | The user's phone number. | |
guest | boolean | Whether the user is a guest. | |
locale | string | The user's locale in POSIX format. Example: en_US. | |
metadata | Hash | The user-level metadata. |
A successful 200 response returns the user. Required fields in the response are user_id and first_name. last_name, phone_number, and locale are optional.
{
"user_id": "kamalsingh1234",
"first_name": "Kamal"
}
Response examples
200 Success
200User created
{
"user_id": "roberteospeedwagon",
"first_name": "Robert",
"last_name": "Speedwagon",
"phone_number": "5555555555",
"guest": false,
"locale": "en_CA",
"metadata": {
"key1": "value1",
"key2": "value2"
}
}
4XX Errors
Error responses return either a single error or multiple errors.
| HTTP Code | Cause | Error Message | Error Code | Error Meta |
|---|---|---|---|---|
400 | Without first name | "can't be blank" | 1001 | {"key":"first_name"} |
400 | Invalid first name | "First name is invalid" | 1001 | {"key":"first_name"} |
400 | Invalid last name | "Last name is invalid" | 1001 | {"key":"last_name"} |
400 | Without user id | "can't be blank" | 1001 | {"key":"user_id"} |
400 | User already created | "A user with this id has already been created" | 1001 | {"key":"user_id"} |
400 | Invalid locale provided | "Unsupported locale" | 1001 | {"key":"locale"} |
400 | Invalid metadata - too many keys | "More than 50 keys" | 1001 | {"key":"metadata"} |
400 | Invalid metadata - long key | "More than 40 char keys" | 1001 | {"key":"metadata"} |
400 | Invalid metadata - long value | "More than 500 char values" | 1001 | {"key":"metadata"} |
404 | Resource not found | "Resource not found" | 4000 | Not applicable |
423 | The target resource is locked | "The target resource is locked." | null | {"key":"user_id"} |
4xx errors
Treat 400 with the message that the user ID is already in use as success. Continue with that user_id.
| HTTP code | Error code | When it occurs | What to do |
|---|---|---|---|
400 | 1001 | Missing user_id. | Include user_id and retry. |
400 | 1001 | User ID already in use. | Treat as success and continue with that user_id. |
400 | 1001 | Missing first_name. | Include first_name and retry. |
400 | 1001 | Invalid first_name. | Remove restricted characters and retry. |
400 | 1001 | Invalid last_name. | Remove restricted characters and retry. |
400 | 1001 | Invalid locale. | Send a supported POSIX locale such as en_US and retry. |
404 | 4000 | User not found. | Confirm the user_id and retry. |
423 | none | Concurrent creation locked the user_id. meta.key is user_id. | Wait briefly and retry. The lock clears automatically. |
For 423 behavior across Carrot Ads, see Error and status codes.
When to create users
- Create the user before you request ads or send events.
- Creation is synchronous. Do not proceed to Get sponsored products until you have a
200or a400already-created response. 423is transient. Wait and retry.400already created means treat as success.
Guest users
Some accounts can create a guest user and later link that history to a registered user. Those endpoints are gated by per-client feature flags. Contact your Instacart representative if you need guest-user support.