> ## Documentation Index
> Fetch the complete documentation index at: https://docs.finowl.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Check cold-email compliance

> Place an email address in a jurisdiction and get that jurisdiction's cold-email rule.

### Good to know

* **Branch on `recommendation_code`.** The `recommendation` and `message` text can change. Treat a code you don't recognize like `case_by_case`.
* **`unknown` is a valid answer.** It means no jurisdiction could be established, so the restrictive `consent_required` default applies. Don't show a country. Free mailboxes like Gmail and Proton usually come back `unknown`, because their domain says nothing about where the person is.
* **`medium` can mean several candidates.** When `jurisdictions_applicable` has more than one entry, the strictest rule was applied and `country_code` is that strictest country.
* **`checking: true` is provisional.** The website check is still running. Send the same request again a few seconds later. Re-checks are free.
* **Repeats are free for 6 months.** The same account looking up the same address again costs 0 credits, and `result_id` stays the same.
* **This is guidance, not legal advice.** The rules are compiled from public sources. Check with counsel before relying on them for a campaign.

<Card title="Guide: cold-email compliance checks" icon="scale-balanced" href="/guides/cold-email-compliance">
  Filter an outreach list by jurisdiction before you send.
</Card>


## OpenAPI

````yaml api-reference/openapi.yaml POST /v1/compliance/email
openapi: 3.1.0
info:
  title: Finowl API
  version: '1.0'
  description: >
    Check emails and passwords against known data breaches, predict gender from
    names

    and emails, check cold-email compliance, validate email addresses and phone
    numbers,

    look up companies by domain and geolocate IP addresses. Every endpoint is a
    JSON

    `POST` authenticated with a bearer API key.
servers:
  - url: https://api.finowl.co
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Breaches
    description: Check whether an email or password appears in known data breaches.
  - name: Gender
    description: Predict gender from a name or email, one at a time or in batches.
  - name: Compliance
    description: >-
      Place an email address in a jurisdiction and return that jurisdiction's
      cold-email rule.
  - name: Email validation
    description: >-
      Check whether an email address can receive mail, and catch typos,
      disposable and role addresses.
  - name: Company
    description: Look up public company details from a domain or work email.
  - name: IP
    description: Geolocate an IP address and flag hosting, proxy and Tor traffic.
  - name: Phone
    description: Validate, format and classify a phone number.
paths:
  /v1/compliance/email:
    post:
      tags:
        - Compliance
      summary: Check cold-email compliance
      description: >
        Places an email address in its most likely jurisdiction and returns that
        jurisdiction's

        cold-email rule. Finowl reads the domain, its mail servers and its
        website. When several

        countries remain possible, the strictest rule applies. When none can be
        established,

        the restrictive `consent_required` default applies.


        A verdict with `checking: true` is provisional while the website check
        finishes. Send the

        same request again a few seconds later to get the settled verdict.


        Costs **1 credit**. Repeat lookups of the same address from the same
        account within

        6 months cost **0 credits**, including re-checks of a provisional
        verdict.


        The rules are guidance compiled from public sources, not legal advice.
      operationId: checkEmailCompliance
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - email
              properties:
                email:
                  type: string
                  format: email
                  maxLength: 254
                  description: >-
                    The address to place in a jurisdiction. Leading and trailing
                    spaces are removed. It must be a plain address with a dotted
                    domain.
                  example: priya.sharma@example.in
      responses:
        '200':
          description: >-
            The check completed. An `unknown` verdict is still a successful
            response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ComplianceResult'
              examples:
                confident:
                  summary: Confident
                  value:
                    email: priya.sharma@example.in
                    country: India
                    country_code: IN
                    email_type: business
                    recommendation_code: allowed_by_policy
                    recommendation: >-
                      Cold email is allowed; India has no specific anti-spam law
                      for email, but personal data must be handled lawfully.
                    message: Cold emailing is allowed under the rules in India.
                    main_laws:
                      - Information Technology Act 2000
                      - Digital Personal Data Protection Act 2023
                    law_reference_urls:
                      - https://www.meity.gov.in/
                    main_restrictions:
                      - Offer a clear opt-out and honour it.
                    applicability: >-
                      National scope; there is no email-specific anti-spam
                      statute.
                    confidence: confident
                    jurisdictions_applicable:
                      - IN
                    signals:
                      points: 5
                      max_points: 10
                      checks: 3
                      latency_ms: 812
                    result_id: 1042
                    credits: 1
                unknown:
                  summary: Unknown
                  value:
                    email: anon@protonmail.com
                    country: ''
                    country_code: ''
                    email_type: consumer
                    recommendation_code: consent_required
                    recommendation: >-
                      We could not place this address in a jurisdiction, so get
                      opt-in consent before emailing it.
                    message: >-
                      We couldn't establish a jurisdiction for this address, so
                      treat it as consent-required.
                    main_laws: []
                    law_reference_urls: []
                    main_restrictions:
                      - >-
                        Treat the address as if the strictest common rule
                        applies: prior consent, sender identification and a
                        working opt-out.
                    applicability: No jurisdiction established; restrictive default.
                    confidence: unknown
                    signals:
                      points: 0
                      max_points: 4
                      checks: 1
                      latency_ms: 0
                    result_id: 1043
                    credits: 1
                provisional:
                  summary: Provisional
                  value:
                    email: sam@example.de
                    country: Germany
                    country_code: DE
                    email_type: business
                    recommendation_code: consent_required
                    recommendation: >-
                      German law requires prior consent for advertising email to
                      businesses as well as consumers.
                    message: >-
                      Cold emailing this address needs prior consent under the
                      rules in Germany. This verdict is provisional while a
                      deeper check runs.
                    main_laws:
                      - Act Against Unfair Competition (UWG) §7
                      - GDPR
                      - ePrivacy Directive 2002/58/EC
                    law_reference_urls:
                      - https://www.gesetze-im-internet.de/uwg_2004/__7.html
                      - https://eur-lex.europa.eu/eli/reg/2016/679/oj
                      - https://eur-lex.europa.eu/eli/dir/2002/58/oj
                    main_restrictions:
                      - >-
                        Unsolicited email advertising is treated as an
                        unreasonable nuisance without prior express consent
                      - for B2B as well as B2C.
                    applicability: >-
                      National implementation of the EU ePrivacy Directive,
                      alongside the GDPR.
                    confidence: medium
                    jurisdictions_applicable:
                      - DE
                    signals:
                      points: 3
                      max_points: 6
                      checks: 2
                      latency_ms: 140
                    checking: true
                    result_id: 1044
                    credits: 1
        '400':
          $ref: '#/components/responses/InvalidInput'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          $ref: '#/components/responses/Unavailable'
        '504':
          $ref: '#/components/responses/Unconfirmed'
components:
  schemas:
    ComplianceResult:
      type: object
      required:
        - email
        - country
        - country_code
        - email_type
        - recommendation_code
        - recommendation
        - message
        - main_laws
        - law_reference_urls
        - main_restrictions
        - applicability
        - confidence
        - signals
        - credits
      properties:
        email:
          type: string
          description: The address that was checked.
        country:
          type: string
          description: >-
            The jurisdiction's country name. Empty when `confidence` is
            `unknown`.
        country_code:
          type: string
          description: >-
            ISO 3166-1 alpha-2 code. Empty when `confidence` is `unknown`. When
            several countries are possible, the code of the strictest one.
        email_type:
          type: string
          enum:
            - consumer
            - business
          description: >-
            `consumer` for personal mailbox providers such as Gmail, otherwise
            `business`.
        recommendation_code:
          type: string
          enum:
            - prohibited
            - consent_required
            - exception_required
            - case_by_case
            - allowed_with_conditions
            - allowed
            - allowed_by_policy
            - safe_to_send
          description: >-
            Machine-readable verdict, strictest first in the list. Branch on
            this, not on `recommendation`. Treat codes you don't recognize like
            `case_by_case`.
        recommendation:
          type: string
          description: Plain-language advice. Wording varies by jurisdiction.
        message:
          type: string
          description: A sentence ready to show to end users.
        main_laws:
          type: array
          items:
            type: string
          description: The laws that govern cold email there.
        law_reference_urls:
          type: array
          items:
            type: string
            format: uri
          description: Official sources for those laws or their regulators.
        main_restrictions:
          type: array
          items:
            type: string
          description: Key obligations when emailing.
        applicability:
          type: string
          description: Scope of the rule.
        confidence:
          type: string
          enum:
            - confident
            - medium
            - unknown
          description: >-
            `confident`: one country backed by two independent checks or a
            single-country mailbox provider. `medium`: a likely country with
            thinner evidence, or several candidates. `unknown`: no jurisdiction
            established.
        jurisdictions_applicable:
          type: array
          items:
            type: string
          description: >-
            Every country still in contention, strictest first. Omitted when
            `unknown`. More than one entry means the strictest rule was applied.
        signals:
          type: object
          description: >-
            Anonymized summary of the checks behind the verdict. `points /
            max_points` is a rough evidence-strength ratio.
          properties:
            points:
              type: integer
              description: Points from checks that produced a usable signal.
            max_points:
              type: integer
              description: Points available from the checks that ran.
            checks:
              type: integer
              description: Number of checks that reported.
            latency_ms:
              type: integer
              description: Combined time of those checks.
        checking:
          type: boolean
          description: >-
            `true` while the website check is still running and the verdict is
            provisional. Omitted when false.
        result_id:
          type: integer
          description: Stable ID of this verdict. It stays the same across repeat calls.
        credits:
          type: integer
          enum:
            - 0
            - 1
          description: '`1` for a charged lookup, `0` for a free repeat within 6 months.'
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
          properties:
            code:
              type: string
              description: >-
                A stable, machine-readable error code. See the Errors page for
                the full list.
              example: invalid_input
  responses:
    InvalidInput:
      description: The request body is not valid. Fix the request before trying again.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: invalid_input
    Unauthorized:
      description: The API key is missing, malformed or revoked.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: unauthorized
    TooManyRequests:
      description: >
        `rate_limited` (too many requests this minute), `quota_exceeded` (not
        enough credits) or

        `provider_rate_limited` (Finowl intelligence is busy). Check the
        `Retry-After` header.
      headers:
        Retry-After:
          description: Seconds to wait before trying again.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: rate_limited
    Unavailable:
      description: >-
        Finowl, or the service behind this endpoint, is temporarily unavailable.
        See the Errors page for whether the request was charged.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: provider_unavailable
    Unconfirmed:
      description: >-
        The lookup did not finish in time. It may or may not have run, and the
        request was charged.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: provider_response_unconfirmed
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Your Finowl API key, for example `finowl_3f9a...`. Create keys in the
        dashboard under **API Keys**.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.