openapi: 3.2.0 info: title: Crust Demo API version: 2.0.0 description: Self-scraped Google and public LinkedIn data as a clean JSON API. servers: - url: https://crustapi.com security: - ApiKeyAuth: [] tags: - name: Demo paths: /v1/demo: get: operationId: demoSearch summary: Public demo (no key, rate-limited) description: A public, rate-limited demo of the search endpoint. No API key. For trying the API without signing up. security: [] parameters: - name: type in: query required: false schema: type: string default: maps enum: - maps - web - name: q in: query required: true schema: type: string responses: '200': description: A small sample of results. content: application/json: schema: $ref: '#/components/schemas/SearchResult' '429': description: Demo rate limit reached. tags: - Demo components: schemas: NewsItem: type: object properties: title: type: string link: type: string snippet: type: - string - 'null' date: type: - string - 'null' source: type: - string - 'null' imageUrl: type: - string - 'null' position: type: integer Review: type: object properties: rating: type: integer date: type: - string - 'null' isoDate: type: - string - 'null' snippet: type: - string - 'null' likes: type: integer description: Total reactions on the review (sum across reaction types). user: type: object properties: name: type: - string - 'null' thumbnail: type: - string - 'null' link: type: - string - 'null' reviews: type: - integer - 'null' photos: type: - integer - 'null' media: type: array items: type: object properties: type: type: string imageUrl: type: string caption: type: string link: type: - string - 'null' id: type: - string - 'null' response: type: - object - 'null' description: Owner reply, when present. properties: date: type: string snippet: type: string Place: type: object description: A place. type=places returns the lean serper-parity subset; type=maps returns this full shape (contact details, categories, opening hours, attributes and photos on top). properties: position: type: integer title: type: string description: Business name. address: type: - string - 'null' latitude: type: - number - 'null' longitude: type: - number - 'null' rating: type: - number - 'null' description: Star rating out of 5. ratingCount: type: - integer - 'null' reviewsCount: type: - integer - 'null' description: 'Maps: exact review count.' reviewsDistribution: type: - object - 'null' description: 'Maps with stars=true: 1-5 star histogram.' category: type: - string - 'null' phoneNumber: type: - string - 'null' website: type: - string - 'null' cid: type: - string - 'null' placeId: type: - string - 'null' priceLevel: type: - string - 'null' description: Google's price band token, e.g. "$1–10". Null when Google shows none. thumbnailUrl: type: - string - 'null' description: A real place photo URL (maps only). bookingLinks: type: array items: type: string description: Reservation/booking URLs when the place is bookable (maps only, sparse). url: type: string description: Google Maps place URL. type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). fid: type: string description: Google feature id (0x…:0x…), usable as an input to type=reviews. type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). street: type: - string - 'null' description: Street line of the address. type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). city: type: - string - 'null' description: type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). state: type: - string - 'null' description: type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). postalCode: type: - string - 'null' description: type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). countryCode: type: - string - 'null' description: ISO country code. type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). location: type: object description: '{lat,lng}. type=maps only (the richer Maps shape; type=places returns the lean serper-parity set).' properties: lat: type: number lng: type: number phone: type: - string - 'null' description: Formatted phone number. Null when Google does not show one. type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). phoneUnformatted: type: - string - 'null' description: E.164-style phone number. type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). categoryName: type: - string - 'null' description: Primary Google category. type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). categories: type: array items: type: string description: All Google categories. type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). totalScore: type: - number - 'null' description: Average star rating (same value as rating). type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). description: type: - string - 'null' description: Google's editorial summary when present. type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). openingHours: type: object additionalProperties: type: string description: Day name to hours string, e.g. {"Monday":"7:30 AM-2 PM"}. type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). permanentlyClosed: type: boolean description: type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). mainImage: type: - string - 'null' description: Primary place photo. type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). attributes: type: object additionalProperties: type: array items: type: string description: Google's attribute groups, e.g. {"Service options":["Takeout"]}. type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). scrapedAt: type: string format: date-time description: When this record was collected. type=maps only (the richer Maps shape; type=places returns the lean serper-parity set). ImageItem: type: object properties: title: type: string imageUrl: type: string imageWidth: type: - integer - 'null' imageHeight: type: - integer - 'null' thumbnailUrl: type: string thumbnailWidth: type: - integer - 'null' thumbnailHeight: type: - integer - 'null' source: type: - string - 'null' description: The publisher's display name as Google shows it. domain: type: - string - 'null' link: type: - string - 'null' googleUrl: type: - string - 'null' position: type: integer creator: type: string description: Image creator from IPTC metadata (sparse — only when Google carries it). copyright: type: string description: Copyright notice from IPTC metadata (sparse). SearchResult: type: object description: Polymorphic result. `searchParameters` echoes your request; the populated array key depends on `type`. properties: searchParameters: type: object additionalProperties: true organic: type: array description: web, scholar, patents, lens items: $ref: '#/components/schemas/OrganicResult' places: type: array description: maps, places items: $ref: '#/components/schemas/Place' news: type: array items: $ref: '#/components/schemas/NewsItem' shopping: type: array items: $ref: '#/components/schemas/ShoppingItem' images: type: array items: $ref: '#/components/schemas/ImageItem' videos: type: array items: $ref: '#/components/schemas/VideoItem' reviews: type: array items: $ref: '#/components/schemas/Review' suggestions: type: array items: $ref: '#/components/schemas/Suggestion' text: type: string description: 'type=webpage: the page''s readable text.' markdown: type: string description: type=webpage with includeMarkdown=true. metadata: type: object description: 'type=webpage: title + og/twitter/article meta.' additionalProperties: true jsonld: description: 'type=webpage: parsed JSON-LD.' nextPageToken: type: string description: 'type=reviews: cursor for the next page.' creditsRemaining: type: - integer - 'null' tookMs: type: integer OrganicResult: type: object description: Web / Scholar / Patents / Lens result. properties: title: type: string link: type: string snippet: type: - string - 'null' date: type: - string - 'null' position: type: integer source: type: - string - 'null' description: Scholar publication info / Lens source site. citedBy: type: - integer - 'null' description: Scholar. assignee: type: - string - 'null' description: Patents. filingDate: type: - string - 'null' description: Patents. imageUrl: type: - string - 'null' description: Lens. thumbnailUrl: type: - string - 'null' description: 'Lens: thumbnail of the matched image.' publicationInfo: type: - string - 'null' description: 'Scholar: authors, journal and year as one line.' year: type: - integer - 'null' description: 'Scholar: publication year parsed from publicationInfo.' pdfUrl: type: - string - 'null' description: 'Scholar: link to the PDF copy when one is offered.' id: type: - string - 'null' description: 'Scholar: Google Scholar cluster id for the result.' htmlUrl: type: - string - 'null' description: 'Scholar: full-text link when the side resource is an HTML copy (pdfUrl is null then).' ShoppingItem: type: object properties: title: type: string source: type: - string - 'null' condition: type: - string - 'null' link: type: - string - 'null' description: Google product page URL (always present since 2026-08). price: type: - string - 'null' imageUrl: type: - string - 'null' description: 'Product thumbnail: a gstatic URL, or an inline data:image URI for some top-of-page rows.' rating: type: - number - 'null' ratingCount: type: - integer - 'null' productId: type: - string - 'null' position: type: integer VideoItem: type: object properties: title: type: string link: type: string snippet: type: - string - 'null' imageUrl: type: - string - 'null' duration: type: - string - 'null' source: type: - string - 'null' channel: type: - string - 'null' date: type: - string - 'null' position: type: integer Suggestion: type: object properties: value: type: string securitySchemes: ApiKeyAuth: type: apiKey in: header name: x-api-key