Searching Array Columns via the REST API Proxy¶
The rest-api-proxy edge function now fully supports PostgREST array operators on text[] columns like contacts.phones, contacts.emails, and contacts.tags.
Fixed
2026-04-22: previously the proxy did not recognize thecs(contains) operator and tried to compare the array column to a literal string, causing:malformed array literal: "cs.{...}". This is now resolved.
Supported operators¶
| Operator | Meaning | Example |
|---|---|---|
cs / contains |
Array contains all of the given values | phones=cs.{"+201017177777"} |
cd / containedBy |
Array is contained by | tags=cd.{"vip","lead"} |
ov / overlaps |
Arrays share at least one value | phones=ov.{"+201017177777","+201111111111"} |
eq, neq, gt, gte, lt, lte, like, ilike, is, in, not, fts, plfts, phfts, wfts |
Standard PostgREST operators | — |
Search a contact by phone number¶
curl -G 'https://txpaxbxhnvnhsjwwaeoy.supabase.co/functions/v1/rest-api-proxy/contacts' \
-H 'X-API-Key: cg_xxx' \
--data-urlencode 'phones=cs.{"+201017177777"}' \
--data-urlencode 'select=id,first_name,last_name,phones,emails' \
--data-urlencode 'limit=1'
Response:
[{
"id": "f2b4f7ab-7033-47ce-be06-b30a47de020a",
"first_name": "mahmoud",
"last_name": null,
"phones": ["+201017177777"],
"emails": ["issmail@gmail.com"]
}]
Search a contact by email¶
curl -G 'https://txpaxbxhnvnhsjwwaeoy.supabase.co/functions/v1/rest-api-proxy/contacts' \
-H 'X-API-Key: cg_xxx' \
--data-urlencode 'emails=cs.{"issmail@gmail.com"}' \
--data-urlencode 'limit=1'
Search by multiple phone numbers (overlap)¶
Returns contacts where any of the listed phones exists in the array:
curl -G 'https://txpaxbxhnvnhsjwwaeoy.supabase.co/functions/v1/rest-api-proxy/contacts' \
-H 'X-API-Key: cg_xxx' \
--data-urlencode 'phones=ov.{"+201017177777","+201111111111"}' \
--data-urlencode 'select=id,phones'
Update a contact found by phone¶
curl -X PATCH -G 'https://txpaxbxhnvnhsjwwaeoy.supabase.co/functions/v1/rest-api-proxy/contacts' \
-H 'X-API-Key: cg_xxx' \
-H 'Content-Type: application/json' \
--data-urlencode 'phones=cs.{"+201017177777"}' \
--data '{"first_name":"Mahmoud Updated"}'
Encoding rules (important)¶
The PostgREST array literal uses curly braces: {"value1","value2"}. The + sign must be URL-encoded to %2B when sent in the raw query string. The safest approach in curl is --data-urlencode, which handles this automatically.
| Source value | What goes on the wire |
|---|---|
phones=cs.{"+201017177777"} (curl --data-urlencode) |
phones=cs.%7B%22%2B201017177777%22%7D |
| Manual encoding | phones=cs.%7B%22%2B201017177777%22%7D |
In Python:
import requests
requests.get(
"https://txpaxbxhnvnhsjwwaeoy.supabase.co/functions/v1/rest-api-proxy/contacts",
headers={"X-API-Key": "cg_xxx"},
params={
"phones": 'cs.{"+201017177777"}',
"select": "id,first_name,phones,emails",
"limit": 1,
},
)
requests URL-encodes the + and braces automatically.
In Node.js (fetch):
const url = new URL("https://txpaxbxhnvnhsjwwaeoy.supabase.co/functions/v1/rest-api-proxy/contacts");
url.searchParams.set("phones", 'cs.{"+201017177777"}');
url.searchParams.set("select", "id,first_name,phones,emails");
url.searchParams.set("limit", "1");
await fetch(url, { headers: { "X-API-Key": "cg_xxx" } });
Common errors¶
| Error | Cause | Fix |
|---|---|---|
malformed array literal: "cs.{...}" |
Old proxy version that didn't recognize cs |
Already fixed — redeploy if you see this again |
malformed array literal: "{ +201..." (note leading space) |
The + was decoded as a space |
Encode + as %2B, or use --data-urlencode |
Empty [] response |
Number stored without + while you searched with + (or vice versa) |
Phones are normalized to E.164 (+<country><number>); always include the + |