Postmark

Table of Contents

Postmark

This service is provided for free from Postmark.

API Documentation

Postmark’s DMARC REST API lets you manage and collect reports on your domain’s DMARC policy. All requests should use SSL encryption by making requests through HTTPS.

HTTP response codes

  • 200 — OK
    Your request was fulfilled.
  • 204 — No Content
    Your request was fulfilled, the response body is empty.
  • 303 — See Other
    Your request is being redirected to a different URI.
  • 400 — Bad Request
    Something with your request isn’t quite right, this could be malformed JSON.
  • 422 — Unprocessable Entity
    Your request has failed validations.
  • 500 — Internal Server Error
    Our servers have failed to process your request.

Authentication

During registration you were provided an API token that you can use for accessing the API. Simply pass this token as X-Api-Token header to the API to perform requests that require authentication. If you forgot your API token you can reset it here.

API Endpoint

https://dmarc.postmarkapp.com

Create a record

Create a new DMARC record for a given domain and email. This endpoint is public and doesn't require authentication.

Request headers

Content-Type required
application/json
Accept required
application/json
post

/records

Example request with curl

curl "https://dmarc.postmarkapp.com/records" \
  -X POST \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"email": "email@domain.com", "domain": "wildbit.com"}'

Body format

email string required
The email address which will receive the weekly digests.
domain string required
The domain which will be monitored.

Example body format

{
  "email": "email@domain.com",
  "domain": "wildbit.com"
}

Response

domain string Domain associated with this record.
public_token string Random token to be inserted into your DNS for identification purpose.
created_at string Timestamp of when the record was created.
private_token string Random token (UUID) to be used for accessing the API.
reporting_uri string URI to send DMARC reports to.
email string Email address that will receive weekly digests for this domain.

Example response

HTTP 200 OK
Content-Type: application/json

{
  "domain": "postmarkapp.com",
  "public_token": "1mVgKNr5scA",
  "created_at": "2014-06-25T19:22:53Z",
  "private_token": "005d8431-b020-41aa-230e-4d63a0357869",
  "reporting_uri": "mailto:randomhash+1mSgANr7scM@inbound.postmarkapp.com",
  "email": "tema@wildbit.com"
}

Get a record

Get a record’s information based off its private token.

Request headers

Accept required
application/json
X-Api-Token required
Your private API token from the welcome email.
get

/records/my

Example request with curl

curl "https://dmarc.postmarkapp.com/records/my" \
  -X GET \
  -H "Accept: application/json" \
  -H "X-Api-Token: 005d8431-b020-41aa-230e-4d63a0357869"

Response

domain string Domain associated with this record.
public_token string Random token to be inserted into your DNS for identification purpose.
created_at string Timestamp of when the record was created.
reporting_uri string URI to send DMARC reports to.
email string Email address that will receive weekly digests for this domain.

Example response

HTTP 200 OK
Content-Type: application/json

{
  "domain": "postmarkapp.com",
  "public_token": "1mVgKNr5scA",
  "created_at": "2014-06-25T19:22:53Z",
  "reporting_uri": "mailto:randomhash+1mSgANr7scM@inbound.postmarkapp.com",
  "email": "tema@wildbit.com"
}

Get DNS snippet

Get generated DMARC DNS record name and value.

Request headers

Accept required
application/json
X-Api-Token required
Your private API token from the welcome email.
get

/records/my/dns

Example request with curl

curl "https://dmarc.postmarkapp.com/records/my/dns" \
  -X GET \
  -H "Accept: application/json" \
  -H "X-Api-Token: 005d8431-b020-41aa-230e-4d63a0357869"

Response

value string Record data to insert into your DNS.
name string DNS record name.

Example response

HTTP 200 OK
Content-Type: application/json

{
  "value": "\"v=DMARC1; p=none; pct=100; rua=mailto:randomhash+1mSgKNr7scM@inbound.postmarkapp.com; sp=none; aspf=r;\"",
  "name": "_dmarc.wildbit.com."
}

Verify DNS

Verify if your DMARC DNS record exists.

Request headers

Accept required
application/json
X-Api-Token required
Your private API token from the welcome email.
post

/records/my/verify

Example request with curl

curl "https://dmarc.postmarkapp.com/records/my/verify" \
  -X POST \
  -H "Accept: application/json" \
  -H "X-Api-Token: 005d8431-b020-41aa-230e-4d63a0357869"

Response

verified boolean Indicates if a valid DNS record exists.

Example response

HTTP 200 OK
Content-Type: application/json

{
  "verified": false
}

Delete a record

Deleting a record will stop processing data for this domain. The email associated with this record will also be unsubscribed from the DMARC weekly digests for this domain only.

Request headers

Accept required
application/json
X-Api-Token required
Your private API token from the welcome email.
delete

/records/my

Example request with curl

curl "https://dmarc.postmarkapp.com/records/my" \
  -X DELETE \
  -H "Accept: application/json" \
  -H "X-Api-Token: 005d8431-b020-41aa-230e-4d63a0357869"

Response

If all goes well, this request will return an empty body.

Example response

HTTP 204 No Response
Content-Type: application/json


List DMARC reports

List all received DMARC reports for a given domain with the ability to filter results by a single date or date range.

Request headers

Accept required
application/json
X-Api-Token required
Your private API token from the welcome email.

Querystring parameters

from_date Only include reports received on this date or after.
to_date Only include reports received before this date.
limit Number of reports to return per request. (default 30, max 50)
after ID of last report returned by previous request. Used for pagination.
get

/records/my/reports

Example request with curl

curl "https://dmarc.postmarkapp.com/records/my/reports?from_date=2014-05-17&to_date=2014-06-17&limit=100&after=4" \
  -X GET \
  -H "Accept: application/json" \
  -H "X-Api-Token: 005d8431-b020-41aa-230e-4d63a0357869"

Response

meta/next integer Next page’s after parameter’s value
meta/next_url string Next page’s URL when the query results do not fit on a single page
meta/total integer Total number of reports matching the query
entries array List of reports matching the query
entries/id integer Report’s ID
entries/external_id string Report’s ID given by reporting organization
entries/organization_name string Reporting organization’s name
entries/domain string Reported domain
entries/date_range_begin string Report’s starting timestamp
entries/date_range_end string Report’s ending timestamp
entries/created_at string Timestamp of when the report was received by our app

Example response

HTTP 200 OK
Content-Type: application/json

{
  "meta": {
    "next": 276,
    "next_url": "/records/e8dad1d4-7162-4c73-8ddf-5be0d64bc2a6/reports?from_date=&to_date=&limit=1&after=276",
    "total": 2
  },
  "entries": [
    {
      "domain": "wildbit.com",
      "date_range_begin": "2014-04-27T20:00:00Z",
      "date_range_end": "2014-04-28T19:59:59Z",
      "id": 276,
      "created_at": "2014-07-25T11:44:55Z",
      "external_id": "xxxxxxxxxxx",
      "organization_name": "google.com"
    }
  ]
}

Get a specific DMARC report by ID

Load full DMARC report details as a raw DMARC XML document or as our own JSON representation.

Request headers

Accept required
application/json, application/xml
X-Api-Token required
Your private API token from the welcome email.
get

/records/my/reports/:id

Example request with curl

curl "https://dmarc.postmarkapp.com/records/my/reports/:id" \
  -X GET \
  -H "Accept: application/json" \
  -H "X-Api-Token: 005d8431-b020-41aa-230e-4d63a0357869"

JSON Response

id integer Report’s ID
domain string Reported domain
date_range_begin string Report’s starting timestamp
date_range_end string Report’s ending timestamp
source_uri string Report’s source URI
external_id string Report’s ID given by reporting organization
email string Reporting organization’s email
organization_name string Reporting organization’s name
created_at string Timestamp of when the report was created
extra_contact_info string Reporting organization’s contact info
records array DMARC authentication results
records/header_from string Payload From domain
records/source_ip string Connecting IP
records/source_ip_version integer Connecting IP’s version
records/host_name string Reverse DNS lookup result for the connecting IP
records/count integer Number of matching messages
records/policy_evaluated_spf string DMARC authentication result for SPF
records/policy_evaluated_dkim string DMARC authentication result for DKIM
records/policy_evaluated_disposition string Applied DMARC disposition
records/policy_evaluated_reason_type string Reason type used to override existing DMARC policy
records/spf_domain string SPF domain
records/spf_result string SPF authentication result
records/dkim_domain string DKIM record’s domain
records/dkim_result string DKIM authentication result

Example JSON response

{
  "id": 276,
  "domain": "wildbit.com",
  "date_range_begin": "2014-04-27T20:00:00Z",
  "date_range_end": "2014-04-28T19:59:59Z",
  "source_uri": "mailto:noreply-dmarc-support@google.com",
  "external_id": "xxxxxxxxx",
  "email": "noreply-dmarc-support@google.com",
  "organization_name": "google.com",
  "created_at": "2014-07-25T11:44:55Z",
  "extra_contact_info": "http://support.google.com/a/bin/answer.py?answer=2466580",
  "records": [
    {
      "header_from": "wildbit.com",
      "source_ip": "127.0.0.1",
      "source_ip_version": 4,
      "host_name": "example.org.",
      "count": 1,
      "policy_evaluated_spf": "fail",
      "policy_evaluated_dkim": "fail",
      "policy_evaluated_disposition": "none",
      "policy_evaluated_reason_type": null,
      "spf_domain": "example.org",
      "spf_result": "pass",
      "dkim_domain": null,
      "dkim_result": null
    }
  ]
}

XML Response

report_metadata General information about the report
report_metadata/org_name Reporting organization’s name
report_metadata/email Reporting organization’s email
report_metadata/extra_contact_info Reporting organization’s contact info
report_metadata/report_id Identifier of the report given by reporting organization
report_metadata/date_range Reported period
report_metadata/date_range/begin Report’s starting timestamp
report_metadata/date_range/end Report’s ending timestamp
policy_published Your DMARC policy’s properties
policy_published/domain Reported domain
policy_published/adkim Alignment mode for DKIM
policy_published/aspf Alignment mode for SPF
policy_published/p Policy-defined action for the domain
policy_published/sp Policy-defined action for subdomains
policy_published/pct Percentage of messages to which the DMARC mechanism is applied
record DMARC authentication results
record/row DMARC authentication results for an IP
record/row/source_ip Connecting IP
record/row/count Number of matching messages
record/row/policy_evaluated Policy evaluation results
record/row/policy_evaluated/disposition Applied DMARC disposition
record/row/policy_evaluated/dkim DKIM evaluation results
record/row/policy_evaluated/spf SPF evaluation results
record/row/identifiers Row identifiers
record/row/identifiers/header_from Payload From domain
record/row/auth_results DKIM and SPF results uninterpreted with respect to DMARC
record/row/auth_results/spf SPF information
record/row/auth_results/spf/domain SPF domain
record/row/auth_results/spf/result SPF authentication result
record/row/auth_results/dkim DKIM information
record/row/auth_results/dkim/domain DKIM domain
record/row/auth_results/dkim/result DKIM authentication result

Example XML response

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<feedback>
  <report_metadata>
    <org_name>google.com</org_name>
    <email>noreply-dmarc-support@google.com</email>
    <extra_contact_info>http://support.google.com/a/bin/answer.py?answer=2466580</extra_contact_info>
    <report_id>xxxxxxxxxxxx</report_id>
    <date_range>
      <begin>1398643200</begin>
      <end>1398729599</end>
    </date_range>
  </report_metadata>
  <policy_published>
    <domain>wildbit.com</domain>
    <adkim>r</adkim>
    <aspf>r</aspf>
    <p>none</p>
    <sp>none</sp>
    <pct>100</pct>
  </policy_published>
  <record>
    <row>
      <source_ip>192.168.170.29</source_ip>
      <count>1</count>
      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>fail</dkim>
        <spf>fail</spf>
      </policy_evaluated>
    </row>
    <identifiers>
      <header_from>wildbit.com</header_from>
    </identifiers>
    <auth_results>
      <spf>
        <domain>example.com</domain>
        <result>pass</result>
      </spf>
    </auth_results>
  </record>
</feedback>

Recover API token

Initiate API token recovery for a domain. This endpoint is public and doesn't require authentication.

Request headers

Content-Type required
application/json
Accept required
application/json
post

/tokens/recover

Example request with curl

curl "https://dmarc.postmarkapp.com/tokens/recover" \
  -X POST \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"owner": "wildbit.com"}'

Body format

owner string required
Domain name or reporting email address at dmarc.postmarkapp.com.

Example body format

{
  "owner": "wildbit.com"
}

Response

recovery_initiated boolean True if recovery email is sent.

Example response

HTTP 200 OK
Content-Type: application/json

{
  "recovery_initiated": true
}

Rotate API token

Generate a new API token and replace your existing one with it.

Request headers

Accept required
application/json
post

/records/my/token/rotate

Example request with curl

curl "https://dmarc.postmarkapp.com/records/my/token/rotate" \
  -X POST \
  -H "Accept: application/json" \
  -H "X-Api-Token: 005d8431-b020-41aa-230e-4d63a0357869" \

Response

private_token string New private token.

Example response

HTTP 200 OK
Content-Type: application/json

{
  "private_token": "115d8431-b020-41aa-230e-4d63a0357869"
}