Skip to content

Add verifly.email API#2722

Open
james-sib wants to merge 1 commit into
APIs-guru:mainfrom
james-sib:add-verifly-email
Open

Add verifly.email API#2722
james-sib wants to merge 1 commit into
APIs-guru:mainfrom
james-sib:add-verifly-email

Conversation

@james-sib

Copy link
Copy Markdown

Adds the Verifly Email Verification API (verifly.email).

Verifly is an agent-native, pay-as-you-go email verification API for developers, SaaS signup validation, bulk list cleaning, and autonomous AI agents. It checks deliverability and syntax, detects disposable / role / catch-all addresses, validates domain MX/DNS health, and exposes usage & credit endpoints.

Notes for the maintainer:

  • Directory version 2.0.0 matches info.version in the spec.
  • The spec is OpenAPI 3.1.0 (the directory already hosts 3.1.x specs).
  • The OpenAPI document is served publicly and unauthenticated at the x-origin URL, so the auto-update scripts can refresh it.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the initial OpenAPI 3.1.0 specification for the Verifly Email Verification API, covering endpoints for onboarding, verification, job management, list cleaning, and billing. The review feedback highlights several key areas to improve the specification's accuracy and usability for client SDK generators. These include explicitly defining the X-Internal-Key header parameter, making authentication optional for checkout endpoints, adding a discriminator to the billing response, enforcing that at least one input field (emails or text) is provided in bulk and file processing requests, and aligning parameter types between JSON and multipart/form-data schemas.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +366 to +371
parameters:
- name: id
in: path
required: true
schema:
type: string

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The description for the /api/v1/jobs/{id}/process endpoint mentions that it accepts an internal service key via the X-Internal-Key header. However, this header is not defined as a parameter in the OpenAPI specification for this endpoint. To ensure client generators and API documentation tools correctly recognize and support this header, it should be explicitly defined as a header parameter.

      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: X-Internal-Key
        in: header
        required: false
        schema:
          type: string
        description: Internal service key to authorize the request.

Comment on lines +980 to +986
/api/checkout:
post:
tags:
- Billing
operationId: createStripeCheckout
summary: Create a Stripe checkout session (API key or session)
description: 'Create a hosted Stripe checkout session for a credit package. Accepts an API key (Authorization: Bearer vf_...) OR a logged-in browser session. Body accepts package_id or packageId.'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The description for /api/checkout states that it "Accepts an API key (Authorization: Bearer vf_...) OR a logged-in browser session." However, because there is no local security override, it inherits the global bearerAuth security requirement. This makes the Bearer token mandatory for all clients and tools (like Swagger UI or SDK generators). To correctly reflect that authentication is optional (e.g., when a browser session is used), you should override the security requirement locally to include an empty security object.

  /api/checkout:
    post:
      tags:
      - Billing
      operationId: createStripeCheckout
      summary: Create a Stripe checkout session (API key or session)
      description: 'Create a hosted Stripe checkout session for a credit package. Accepts an API key (Authorization: Bearer vf_...) OR a logged-in browser session. Body accepts package_id or packageId.'
      security:
      - bearerAuth: []
      - {}

Comment on lines +1011 to +1017
/api/checkout/crypto:
post:
tags:
- Billing
operationId: createCryptoCheckout
summary: Create a crypto (Plisio) checkout (API key or session)
description: Create a Plisio crypto invoice for a credit package. Accepts an API key OR a logged-in browser session. Body accepts package_id or packageId and an optional currency (BTC/ETH/LTC/USDT/USDC); when currency is supplied the response includes a raw wallet address + amount + qr_code.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The description for /api/checkout/crypto states that it "Accepts an API key OR a logged-in browser session." However, because there is no local security override, it inherits the global bearerAuth security requirement. This makes the Bearer token mandatory for all clients and tools (like Swagger UI or SDK generators). To correctly reflect that authentication is optional (e.g., when a browser session is used), you should override the security requirement locally to include an empty security object.

  /api/checkout/crypto:
    post:
      tags:
      - Billing
      operationId: createCryptoCheckout
      summary: Create a crypto (Plisio) checkout (API key or session)
      description: Create a Plisio crypto invoice for a credit package. Accepts an API key OR a logged-in browser session. Body accepts package_id or packageId and an optional currency (BTC/ETH/LTC/USDT/USDC); when currency is supplied the response includes a raw wallet address + amount + qr_code.
      security:
      - bearerAuth: []
      - {}

Comment on lines +969 to +972
schema:
oneOf:
- $ref: '#/components/schemas/StripeCheckoutResult'
- $ref: '#/components/schemas/CryptoCheckoutResult'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The response for /api/v1/billing POST uses oneOf to return either StripeCheckoutResult or CryptoCheckoutResult. Both schemas contain a method property with a constant value (stripe or crypto). Adding an explicit discriminator mapping on the method field will allow client SDK generators to produce clean, strongly-typed polymorphic classes/interfaces instead of generic union types.

              schema:
                oneOf:
                - $ref: '#/components/schemas/StripeCheckoutResult'
                - $ref: '#/components/schemas/CryptoCheckoutResult'
                discriminator:
                  propertyName: method
                  mapping:
                    stripe: '#/components/schemas/StripeCheckoutResult'
                    crypto: '#/components/schemas/CryptoCheckoutResult'

Comment on lines +1433 to +1454
BulkVerificationRequest:
type: object
properties:
emails:
type: array
minItems: 1
maxItems: 1000000
items:
type: string
maxLength: 254
text:
type: string
description: Raw text/CSV to extract emails from when 'emails' is not provided.
filename:
type: string
maxLength: 255
default: bulk_upload.csv
webhook_url:
type: string
format: uri
description: Optional public HTTPS webhook called when the job completes.
additionalProperties: false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In BulkVerificationRequest, both emails and text are marked as optional. This allows clients to send an empty JSON object {}, which is semantically invalid. Using anyOf at the schema level enforces that at least one of these input methods is provided, improving validation and client-side error prevention.

    BulkVerificationRequest:
      type: object
      properties:
        emails:
          type: array
          minItems: 1
          maxItems: 1000000
          items:
            type: string
            maxLength: 254
        text:
          type: string
          description: Raw text/CSV to extract emails from when 'emails' is not provided.
        filename:
          type: string
          maxLength: 255
          default: bulk_upload.csv
        webhook_url:
          type: string
          format: uri
          description: Optional public HTTPS webhook called when the job completes.
      anyOf:
      - required: [emails]
      - required: [text]
      additionalProperties: false

Comment on lines +1754 to +1796
FileProcessRequest:
type: object
properties:
emails:
type: array
items:
type: string
text:
type: string
options:
type: object
properties:
deduplicate:
type: boolean
default: true
exclude_public_domains:
type: boolean
remove_public:
type: boolean
exclude_role_accounts:
type: boolean
remove_role:
type: boolean
remove_disposable:
type: boolean
domain_blacklist:
type: array
items:
type: string
pattern_blacklist:
type: array
items:
type: string
verify:
type: boolean
default: false
description: Verify each email (costs credits).
save:
type: boolean
default: false
description: Save the result as a downloadable file.
filename:
type: string

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to BulkVerificationRequest, FileProcessRequest allows both emails and text to be omitted, which could result in an empty and invalid request. Adding an anyOf block ensures that at least one of these input fields is supplied.

    FileProcessRequest:
      type: object
      anyOf:
      - required: [emails]
      - required: [text]
      properties:
        emails:
          type: array
          items:
            type: string
        text:
          type: string
        options:
          type: object
          properties:
            deduplicate:
              type: boolean
              default: true
            exclude_public_domains:
              type: boolean
            remove_public:
              type: boolean
            exclude_role_accounts:
              type: boolean
            remove_role:
              type: boolean
            remove_disposable:
              type: boolean
            domain_blacklist:
              type: array
              items:
                type: string
            pattern_blacklist:
              type: array
              items:
                type: string
            verify:
              type: boolean
              default: false
              description: Verify each email (costs credits).
            save:
              type: boolean
              default: false
              description: Save the result as a downloadable file.
            filename:
              type: string

Comment on lines +481 to +484
verify:
type: string
save:
type: string

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In the /api/v1/files POST endpoint, the multipart/form-data schema defines verify and save as type: string. However, in the JSON-equivalent FileProcessRequest schema, these options are defined as type: boolean. To maintain consistency and ensure client SDKs generate correct boolean parameters for both content types, these fields should be defined as type: boolean in the multipart schema as well.

                verify:
                  type: boolean
                  default: false
                save:
                  type: boolean
                  default: false

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant