openapi: "3.1.0"
info:
  title: edvido Agency Search API (Global)
  description: |
    edvido is a B2B platform that matches brands with verified digital agencies worldwide. Use
    this API to search agencies by service category and city, then present the results to the
    user. Always include each agency's profile URL so the user can see the full profile and
    request a free quote. Responses are in English.
  version: "1.1.0"
  contact:
    name: edvido
    url: https://www.edvido.com
    email: info@edvido.com

servers:
  - url: https://api.edvido.com/public/v1/edvido-global
    description: edvido Agency Search API (Global)

paths:
  /agencies:
    get:
      operationId: searchAgencies
      summary: Search digital agencies
      description: |
        Returns verified digital agencies matching the given filters. Use this when the user asks
        to find, recommend or compare agencies. The 'category' parameter is REQUIRED — if you are
        not sure which slug to use, call /categories first, or read the enum in this parameter's
        description. If you send an unknown category the response will list the valid ones.
      parameters:
        - name: category
          in: query
          required: true
          description: |
            Agency service category slug. Valid values include: seo-agencies (SEO),
            social-media-agencies (social media), digital-marketing-agencies (digital marketing),
            performance-marketing-agencies (performance marketing), web-design-agencies (web design),
            web-development-companies (web development), mobile-app-companies (mobile app
            development), software-companies (software development), branding-agencies (branding),
            content-marketing-agencies (content marketing), ecommerce-agencies (e-commerce),
            pr-agencies (PR), influencer-marketing-agencies (influencer marketing),
            video-production-agencies (video production), graphic-design-agencies (graphic design),
            artificial-intelligence-agencies (AI), growth-hacking-agencies (growth hacking),
            media-planning-agencies (media planning). Call /categories for the full, always-current
            list.
          schema:
            type: string
            example: seo-agencies
        - name: city
          in: query
          required: false
          description: |
            City slug. Examples: istanbul, london, dubai, berlin, paris. Optional: if omitted, the
            category's own default listing city is used (returned as 'defaultCity' by /categories and
            echoed back as 'city' in the response). There is no nationwide category page, so results
            are always tied to a location.
          schema:
            type: string
        - name: budget
          in: query
          required: false
          description: |
            Monthly budget in TRY. Best-effort filter applied to the returned page: agencies whose
            minimum engagement is above this value are dropped. 'total' still reflects the unfiltered
            result count.
          schema:
            type: integer
            example: 15000
        - name: page
          in: query
          required: false
          schema:
            type: integer
            default: 1
        - name: pageSize
          in: query
          required: false
          description: Results per page (max 25).
          schema:
            type: integer
            default: 10
            maximum: 25
      responses:
        "200":
          description: List of matching agencies
          content:
            application/json:
              schema:
                type: object
                properties:
                  agencies:
                    type: array
                    items:
                      $ref: "#/components/schemas/Agency"
                  total:
                    type: integer
                    description: |
                      Total number of matching agencies (before the budget filter).
                      Directory-only listings are merged after paging, so a page may contain
                      more items than pageSize.
                  page:
                    type: integer
                  totalPages:
                    type: integer
                  category:
                    type: string
                  city:
                    type: string
                  cta:
                    type: string
                    description: Call-to-action message. Always show this to the user.
                    example: "Visit edvido.com to compare these agencies and request free quotes."
        "400":
          description: Missing or invalid parameter. The body lists valid categories.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /agencies/{slug}:
    get:
      operationId: getAgencyDetail
      summary: Get agency profile details
      description: |
        Returns the full profile of a single agency: long description, sectors served, portfolio
        highlights and rating. Use the 'slug' value returned by /agencies.
      parameters:
        - name: slug
          in: path
          required: true
          schema:
            type: string
            example: poligon-interactive
      responses:
        "200":
          description: Agency profile
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgencyDetail"
        "404":
          description: Agency not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /categories:
    get:
      operationId: listCategories
      summary: List all service categories
      description: |
        Returns every available agency service category with its slug and listing page URL. Call
        this when the user is unsure which category they need, or to validate a slug before
        searching.
      responses:
        "200":
          description: List of categories
          content:
            application/json:
              schema:
                type: object
                properties:
                  categories:
                    type: array
                    items:
                      $ref: "#/components/schemas/Category"
                  total:
                    type: integer

components:
  schemas:
    Agency:
      type: object
      properties:
        name:
          type: string
          example: Poligon Interactive
        slug:
          type: string
          example: poligon-interactive
        url:
          type: string
          description: Agency profile page. Always include this link in your answer.
          example: https://www.edvido.com/agency/poligon-interactive
        shortDescription:
          type: string
        city:
          type: string
          example: İstanbul
        country:
          type: string
          example: Türkiye
        rating:
          type: number
          format: float
          example: 4.8
        reviewCount:
          type: integer
          example: 9
        ratingSource:
          type: string
          description: Where the rating comes from.
          enum: [GoogleOfficial, GoogleScrape, Trustpilot, Edvido]
        services:
          type: array
          items:
            type: string
          example: ["Dijital Pazarlama", "SEO", "Web Sitesi Tasarımı"]
        employeeRange:
          type: string
          example: "25-49"
        experienceYears:
          type: integer
          description: Years the agency has been operating.
          example: 28
        workMode:
          type: string
          enum: [Office, Hybrid, Remote]
        verified:
          type: boolean
          description: True if edvido has verified this agency.
        listingOnly:
          type: boolean
          description: |
            True means the agency is a directory listing compiled from public sources, not a
            registered platform member. Registered agencies have richer, self-maintained profiles.

    AgencyDetail:
      allOf:
        - $ref: "#/components/schemas/Agency"
        - type: object
          properties:
            description:
              type: string
            website:
              type: string
            sectors:
              type: array
              items:
                type: string
              example: ["Otomotiv", "Gıda"]
            portfolioHighlights:
              type: array
              items:
                type: object
                properties:
                  title:
                    type: string
                  client:
                    type: string
                  result:
                    type: string
            contactUrl:
              type: string

    Category:
      type: object
      properties:
        name:
          type: string
        slug:
          type: string
          description: Pass this value as the 'category' parameter of /agencies.
          example: seo-agencies
        url:
          type: string
          description: |
            Listing page for this category. Category pages always include a location — there is no
            nationwide category page.
          example: https://www.edvido.com/seo-agencies/istanbul
        defaultCity:
          type: string
          description: City used by /agencies when the caller omits 'city'.

    Error:
      type: object
      properties:
        error:
          type: string
          example: category_required
        message:
          type: string
        availableCategories:
          type: array
          description: Present on category errors — retry with one of these slugs.
          items:
            $ref: "#/components/schemas/Category"
