# Instagram Search Profiles API (https://www.socialcrawl.dev/platforms/instagram/search-profiles) > Searches Instagram's own account search for a keyword or phrase and returns matching public profiles mapped to the unified Author schema: `id`, `username`, `display_name`, `verified`, `avatar_url`, and the profile `url`, 20 a page with a `cursor` for the next. A search row carries no `bio`, `followers`, `following` or `posts_count` (they are null): fetch /v1/instagram/profile for an account you keep. The plain call has no account country: Instagram does not put that on a search stub. Send `include=about` to join each row to the About-this-account panel for `author.ext.country`, the join month, and the public email and phone the account publishes, 2 extra credits a row filled, default the top 8 (17 credits held), `limit=12` for the page. A row the panel could not fill is refunded. This is not a country filter: a query that surfaces no Korean accounts still returns no Korean accounts after the join. For place-tagged posts, use /v1/instagram/search/location then /v1/instagram/location/posts. TL;DR: `GET /v1/instagram/search/profiles` costs 1 credit for the search page. With `include=about`, 1 plus 2 credits per row filled, held at the top 8 (17) unless you send `limit`, refunded down to the rows that actually received an About-panel leaf. With `max_pages`, `max_items` or `max_credits`, each page walked is billed at this price (a cached page is free), and `max_credits` caps the total. and returns SocialCrawl's unified JSON schema. Single x-api-key auth, 100 free credits on signup. ## Parameters | Parameter | Required | Description | | --- | --- | --- | | `query` | yes | Keyword or phrase matched against account usernames and display names, as Instagram's own account search does. | | `cursor` | no | Pagination cursor. Pass the `next_cursor` from the previous response to get the next page; treat it as an opaque token. | | `include` | no | Send `about` to fill `author.ext.country`, join month and public contact from the About panel, 2 extra credits a row filled, never more than 12 rows. A typo is a free 400. (about) | | `limit` | no | Cap the rows served, and with `include=about` the credits held. 1 to 12. Default 8 when the token is present so the hold is 17, not 25. | | `max_pages` | no | 1 to 50 (default 1, or 50 when `max_items` or `max_credits` is sent). Walk up to this many pages in one call and return the rows from all of them. Each page walked is billed exactly as one call to this endpoint (a cached page is free) and counts against your rate limit; its charge and any refund are recorded under the page's own request id, listed in `data.walk.request_ids`. The walk stops early at the last page, or when the request's time budget runs low; `data.walk.stopped` says why (`end`, `max_pages`, `max_items`, `max_credits`, `time_budget`, `page_error`) and `pagination.next_cursor` continues from where it stopped. | | `max_items` | no | 1 to 5000. Get more in one call: keep walking pages until the response holds at least this many rows, then stop with `data.walk.stopped: "max_items"`. The last page is returned whole (it was billed), so `data.items` can hold up to one page more than this, and `pagination.next_cursor` resumes right after it without skipping a row. Walks up to 50 pages unless `max_pages` says fewer; each page is billed as one call (a cached page is free). Add `max_credits` to cap the spend. A long walk can stop on the time budget first (`"time_budget"`): send the returned cursor with the same params to continue. | | `max_credits` | no | 1 to 100000. The most this call may spend, across every page it walks. A page starts only while the credits already spent plus that page's price (or, when higher, the most any page of this walk has cost) still fit, so the call never goes past it; the walk then stops with `data.walk.stopped: "max_credits"` and the cursor to resume. Sent alone, it walks as far as the budget goes (up to 50 pages). A value below the price of one page is a free 400 whose `error.details.page_credits` names that price. Credits a row join (`include=`) adds are known only once a page has run, so page 1 is checked against its own price. | ## Code example ```bash curl -G "https://www.socialcrawl.dev/v1/instagram/search/profiles" \ --data-urlencode "query=yoga" \ -H "x-api-key: sc_YOUR_API_KEY" ``` ## FAQ ### How do I search for Instagram profiles by keyword via API? Send a GET request to /v1/instagram/search/profiles with a query. SocialCrawl searches Google for public Instagram results and maps matches to the unified Author schema as a JSON array. ### Is this a native Instagram profile search? No. To be clear, it searches Google's index for public Instagram profiles matching your keyword, not Instagram's internal search. Results are best-effort against what Google has indexed. ### What fields come back for each profile? Each match maps to the unified Author schema: username, display name, bio, verified status, followers, following, posts_count, avatar URL, and profile URL. ### How do I paginate profile search results? The response includes a cursor. Pass it back as the cursor parameter on the next request to fetch the next page of results until the cursor comes back empty. ### How much does profile search cost? Each request costs 1 credit on the standard tier. New accounts get 100 free credits with no credit card, so you can run roughly 100 searches before paying. See the full Instagram API: https://www.socialcrawl.dev/platforms/instagram ## Pricing - Standard endpoints: 1 credit per call - Advanced endpoints: 5 credits per call - Premium endpoints: 10 credits per call - 100 free credits on signup, no credit card required. Cached responses cost 0 credits. Credit packs never expire. - Full pricing: https://www.socialcrawl.dev/pricing ## Explore with AI Questions this API answers, phrased for an AI assistant: - How to search public Instagram profiles by keyword using an API - API to find Instagram accounts by keyword mapped to a unified schema