Skip to content
SearchJet
Updated October 1, 2026

Basic Usage

You search SearchJet by calling one REST endpoint, GET /api/v1/search. This page covers the three things most integrations need: a simple search, filters, and pagination. Each example comes in three versions: curl, JavaScript fetch, and Laravel's built-in HTTP client.

There's no package to install. If you use Laravel and haven't set up your keys yet, follow Step-by-Step Installation & Configuration first.

Before you start

Searching uses your public search key, shown on the dashboard's Sites list as "Public Key". It's read-only, so you can use it in browser code. Don't use the private key here: it returns 401 INVALID_API_KEY. See API Key Setup.

Authorization: Bearer YOUR_PUBLIC_KEY
Accept: application/json
curl -G "https://app.searchjetengine.com/api/v1/search" \
  -H "Authorization: Bearer $SEARCHJET_PUBLIC_KEY" \
  -H "Accept: application/json" \
  --data-urlencode "q=laravel"
async function search(query, extra = {}) {
  const params = new URLSearchParams({ q: query, ...extra });
  const res = await fetch(`https://app.searchjetengine.com/api/v1/search?${params}`, {
    headers: { Authorization: 'Bearer YOUR_PUBLIC_KEY', Accept: 'application/json' },
  });
  if (!res.ok) throw new Error(`Search failed: ${res.status}`);
  return res.json();
}

const data = await search('laravel');
for (const hit of data.results) {
  console.log(hit.title, hit.url);
}
console.log(`About ${data.total} matches`);
use Illuminate\Support\Facades\Http;

$hits = Http::withToken(config('services.searchjet.public_key'))
    ->acceptJson()
    ->get('https://app.searchjetengine.com/api/v1/search', ['q' => 'laravel'])
    ->throw()
    ->json('results');

foreach ($hits as $hit) {
    echo $hit['title'];
    echo $hit['excerpt'] ?? '';
}

results is the array of hits, ranked by relevance. The fields in each hit depend on your plan:

  • Free returns id, title, url, type, thumbnail, price, currency and sku, with no excerpt or content.
  • Pro adds excerpt, content, author, date, image and more.
  • Growth and Enterprise return every stored field.

Write your display code so it still works when optional fields are missing. The response also includes total (an estimate), limit, offset, page, processing_time_ms and remaining_quota. See the REST API Reference.

Adding filters

Use the filters parameter. It takes a Meilisearch filter expression:

type = "post"
type = "product" AND price < 50

On Free, you can filter only on id, title, type, price, currency and sku. On paid plans, you can filter on any attribute marked filterable in Index Settings – General Attributes. Anything else returns 400 INVALID_FILTER.

curl -G "https://app.searchjetengine.com/api/v1/search" \
  -H "Authorization: Bearer $SEARCHJET_PUBLIC_KEY" \
  -H "Accept: application/json" \
  --data-urlencode "q=framework" \
  --data-urlencode 'filters=type = "post"'
const { results } = await search('framework', { filters: 'type = "post"' });
$hits = Http::withToken(config('services.searchjet.public_key'))
    ->acceptJson()
    ->get('https://app.searchjetengine.com/api/v1/search', [
        'q' => 'framework',
        'filters' => 'type = "post"',
    ])
    ->throw()
    ->json('results');

URLSearchParams, Laravel's HTTP client and curl's --data-urlencode all URL-encode the filter for you.

Pagination

Set the page size with limit (1 to 100, default 20). Then choose which page to fetch with either page or offset. If you send both, offset wins, so send only one.

# Page 2, 20 results per page
curl -G "https://app.searchjetengine.com/api/v1/search" \
  -H "Authorization: Bearer $SEARCHJET_PUBLIC_KEY" \
  -H "Accept: application/json" \
  --data-urlencode "q=wordpress" \
  --data-urlencode "limit=20" \
  --data-urlencode "page=2"
async function searchPage(query, page = 1, perPage = 20) {
  const data = await search(query, { limit: String(perPage), page: String(page) });
  return {
    hits: data.results,
    page: data.page,
    totalPages: Math.ceil(data.total / data.limit),
  };
}
$response = Http::withToken(config('services.searchjet.public_key'))
    ->acceptJson()
    ->get('https://app.searchjetengine.com/api/v1/search', [
        'q' => 'wordpress',
        'limit' => 20,
        'page' => $request->integer('page', 1),
    ])
    ->throw();

$hits = $response->json('results');
$totalPages = (int) ceil($response->json('total') / $response->json('limit'));

total is an estimate, so treat the page count as approximate.

Sorting

Pass sort as attribute:asc or attribute:desc, for example sort=price:asc. Free can sort on one field: id, title or price. Paid plans can sort on up to five sortable attributes, comma-separated.

Server-side search and rate limits

The search endpoint allows 30 requests per minute per client IP. In a browser, every visitor gets their own budget. If you search from a Laravel controller, though, all of your visitors share your server's single budget. For busy sites, either call search from the browser, or cache server-side results:

$hits = Cache::remember('search:' . md5($q), 300, fn () =>
    Http::withToken(config('services.searchjet.public_key'))
        ->acceptJson()
        ->get('https://app.searchjetengine.com/api/v1/search', ['q' => $q])
        ->throw()
        ->json('results')
);

See Rate Limits & Quotas.

Next steps

Was this article helpful?

Ready to add search to your project?

Start free. No credit card required. Deploy in under 10 minutes.