# Developer Documentation

Welcome to the Maildrop developer docs!

<div align="left"><figure><img src="/files/wr9QeKzmEUWcV95dTyI2" alt="A woman sitting with a laptop"><figcaption></figcaption></figure></div>

Maildrop provides an easy-to-use API that lets you programmatically retrieve mailbox listings and individual messages, delete messages, and more.

### Maildrop Architecture

Maildrop is built on a very straightforward architecture - as messages come in, they are checked against a variety of antispam filters written by [Heluna](https://heluna.com/). Messages which pass the filters get immediately queued and placed into a database.

{% hint style="info" %}
The first time you email a maildrop.cc address from a mail server that Maildrop hasn't seen before, Maildrop will respond with a temporary failure telling your mail server to try again. This is a concept known as "[greylisting](https://en.wikipedia.org/wiki/Greylisting_\(email\))", which is one effective antispam technique. Most mail servers will retry their delivery within 15 minutes, which Maildrop will then accept.
{% endhint %}

### Temporary, Throwaway Mailboxes

Maildrop mailboxes are *temporary*; that is, if a mailbox doesn't get a message within 24 hours, it erases all of its messages. Additionally, during periods of high usage, mailboxes which have not had a message added recently may be evicted to make space for new messages.

Maildrop mailboxes can hold a maximum of **10 messages**, after which the oldest messages will be deleted.

### Sending Email from Maildrop

Maildrop **can not send email** under any circumstances. The SPF record for Maildrop is set so that no host on the internet should be sending messages from the maildrop.cc domain - you can (and should) ignore all emails from a maildrop.cc address.

```bash
% nslookup -type=txt maildrop.cc
Server:		100.100.100.100
Address:	100.100.100.100#53

Non-authoritative answer:
maildrop.cc	text = "v=spf1 -all"
```


# Quickstart

This page helps you get up and running with the Maildrop API within ten minutes.

The Maildrop API is based on [GraphQL](https://graphql.org/), which allows for an easy HTTP API integration with your codebase. The maildrop.cc website uses the Apollo GraphQL client to access the API, and this document will help show how to create raw HTTP requests or use the prebuilt Apollo Javascript library.

#### See Also

* [How to query with GraphQL](https://graphql.org/learn/queries/)&#x20;
* [Apollo React Library](https://www.apollographql.com/docs/react/)
* [Apollo Swift Library](https://www.apollographql.com/docs/ios/)
* [Apollo Kotlin Library](https://www.apollographql.com/docs/kotlin/)

### Quickstart - curl

```bash
curl --request POST \
    --header 'content-type: application/json' \
    --url https://api.maildrop.cc/graphql \
    --data '{"query":"query Example {\n  ping(message:\"hello, world!\")\n}"}'
```

should return

```
{"data":{"ping":"pong hello, world!"}}
```

{% hint style="info" %}
The API is hosted at **<https://api.maildrop.cc/graphql>** and only accepts POST requests, and these requests *must* have a Content-Type header set to "application/json".
{% endhint %}

### Quickstart - React

1. Install the Apollo React library into your project

```bash
npm install --save @apollo/client graphql
```

2. Set up the schema for your Apollo client

```typescript
export const typeDefs = gql`
    type Query {
        ping(message: String): String
        inbox(mailbox: String!): [Message]
        message(mailbox: String!, id: String!): Message
        altinbox(mailbox: String!): String
        statistics: Statistics
        status: String
    }
    type Mutation {
        delete(mailbox: String!, id: String!): Boolean
    }
    type Message {
        id: String
        subject: String
        date: String
        headerfrom: String
        data: String
        html: String
    }
    type Statistics {
        blocked: Int
        saved: Int
    }
`;
```

3. Set up your GraphQL client object

```typescript
export const client = new ApolloClient({
    uri: "https://api.maildrop.cc/graphql",
    cache: new InMemoryCache(),
    typeDefs
});
```

4. Set up a test GraphQL query

```typescript
export const TEST_QUERY = gql`
    query Test($message: String!) {
        ping(message: $message)
    }
`;
```

5. Set up a component to run the query and display the results

```tsx
import * as React from "react";
import { useQuery } from "@apollo/client";
import { TEST_QUERY } from "./gql";

interface QueryVariables {
    message: string;
}

interface QueryReturn {
    message: string;
}

interface TestComponentProps {
    message: string;
}

const TestComponent = (props: TestComponentProps) => {
    const { loading, error, data } = useQuery<QueryReturn, QueryVariables>(TEST_QUERY, {
        variables: { message: props.message }
    });
    return (
        <div>
            {loading && <div>Loading...</div>}
            {error && <div>There was an error.</div>}
            {!loading && data?.message && <div>Return: {data.message}</div>}
        </div>
    );
};

export default const App = () => {
    return (
        <div>
            <TestComponent message="Hello, world!" />
        </div>
    );
};
```

You should see a page which returns the text "Return: pong Hello, world!". The Apollo library is extremely powerful, and takes care of the raw HTTP requests, authentication, caching, JSON parsing, and so on. It acts as a React hook, so as the request starts, the loading boolean automatically changes, triggering a re-render, and then when the data comes in for the request, another re-render is automatically done.

{% hint style="info" %}
The **ping resolver** returns whatever message you send to it appended to the word "pong". Try it out! GraphQL queries can take a variable as an argument to the resolver, which is specified in the *schema* in step 2. That schema is the exact schema which maildrop.cc uses to access the API.
{% endhint %}


# Overview

This page gives you all the information you need to start connecting to the Maildrop API and performing queries.

### Connect to the API

The Maildrop API is located at `https://api.maildrop.cc/graphql` and only allows secured connections.

All requests must be valid GraphQL queries or mutations; any other query will fail with an error message.

#### See Also

* [Maildrop Quickstart](/quickstart)
* [GraphQL](/api-reference/graphql-api-schema)

### Authentication and Request Requirements

The Maildrop API currently requires no authentication. At some point in the future, there may be a requirement of a bearer token to perform queries if rate limiting is insufficient to stop high-volume query batches.

The only requirement is that every request must have the **Content-Type** header set to **application/json**. Without this header, the request will fail with an error message.

As with other GraphQL APIs, every request to the Maildrop API must be an HTTP **POST**.

### Request Formatting

Other than the formatting for GraphQL, there are no specific requirements for formatting a request to the API. Valid user agent strings, correct Accept headers for compression, and any header that you would set for a "normal" API request should all be set when accessing the Maildrop API.

Cache-Control headers will be ignored by the API - caching is done within the Maildrop architecture and trying to evict caches with the Cache-Control header will not work.

### Reference: List of API Methods

| API Method                                                      | Sample Query                                                                                     | Parameters                             |
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------- |
| Echo Resolver                                                   | ping(message: "Hello, world!")                                                                   | $message: String                       |
| [Get a Mailbox Listing](/api-reference/get-a-mailbox-listing)   | inbox(mailbox: "testing")                                                                        | $mailbox: String                       |
| [Get a Specific Message](/api-reference/get-a-specific-message) | message(mailbox: "testing", id: "abc123")                                                        | <p>$mailbox: String<br>$id: String</p> |
| [Delete a Message](/api-reference/delete-a-message)             | <p>delete(mailbox: "testing", id: "abc123")<br><br><strong>Note</strong>: this is a mutation</p> | <p>$mailbox: String<br>$id: String</p> |
| [Get a Mailbox Alias](/api-reference/get-a-mailbox-alias)       | altinbox(mailbox: "testing")                                                                     | $mailbox: String                       |
| [Maildrop Statistics](/api-reference/maildrop-statistics)       | statistics                                                                                       |                                        |
| [Service Status](/api-reference/service-status)                 | status                                                                                           |                                        |

#### See Also

* [GraphQL API Schema](/api-reference/graphql-api-schema#the-full-graphql-schema-for-maildrop)


# Rate Limiting

This page provides information about the Maildrop API service limits.

### How fast can I query the Maildrop API?

The Maildrop API rate limits connections within **10-second windows of time**. Within those 10 seconds, you can make **up to 50 queries**, for an average of **5 queries per second**.

In theory, you could burst to up to 25 queries at once, assuming that you have done a burst of a similar number of queries within the allotted window of time.

In reality, your sustained query rate should probably stay around **1 or 2 queries per second**, simply because of the rate that the mail server will accept new messages. Retrieving a list of messages for a mailbox more often than once every ten seconds or so is wasteful.

### What happens if I get rate limited?

Connections will start getting dropped with a 429 response code. Continued connections will see this 429 response code until they back off for the window of time, when the number of queries resets.

Continued rate limiting may result in your connections being **completely denied**, so please take care in how often you're accessing the API.

### What if I need to query the API faster than the rate limit?

**Please** [**get in touch**](https://maildrop.cc/contact-us/). Custom API servers and entire Maildrop clusters can be set up for dedicated use. Prior to inquiries about dedicated hardware, you should investigate your usage of the API and whether you really need to be querying incoming mailboxes faster than 5 times per second. (Sample some of your million rows rather than testing every one!)


# GraphQL API Schema

This page provides general information about GraphQL and the reference schema for Maildrop.

### What's GraphQL?

From the [GraphQL foundation](https://graphql.org/):

> GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

Put another way, GraphQL is a modern, more structured and standardized way of querying APIs. Understanding the core GraphQL terms lets developers consume any GraphQL API without needing specialized knowledge about the API itself.

Here's a sample GraphQL query and response:

```graphql
query PingSample {
    ping(message: "Hello, world!")
}
```

```json
{"data":{"ping":"pong Hello, world!"}}
```

### Why GraphQL and not REST?

Maildrop is using GraphQL for three primary reasons:

* **Give client developers freedom** - rather than having a REST API that returns every piece of data on every request, GraphQL requests specify which pieces of data they need. This can greatly speed up data transfer and makes overall performance faster.
* **Easy ramp-up for existing GraphQL users** - once a developer understands queries and mutations, and how to format them, every GraphQL API behaves exactly the same. The overall time to roll out a functional prototype using GraphQL is much faster than a traditional REST API.
* **Ability for developers to run multiple queries in one request** - Rather than having multiple connections to multiple REST API endpoints, one GraphQL query can specify multiple pieces of data; for example, the maildrop.cc site requests the list of messages in a mailbox while also asking for the mailbox alias for that mailbox.

### Which GraphQL library should I use?

[Apollo](https://www.apollographql.com/) is a very fully-featured library with support for Javascript/Typescript, Swift, and Kotlin. While it's certainly possible to write your own HTTP transport library to make GraphQL queries and mutations, using the Apollo library takes care of otherwise-time-consuming tasks such as marshaling/un-marshaling JSON, caching data locally, transforming data as it appears, handling data refetching, and so on. Apollo will speed up development times when dealing with any GraphQL API.

#### **See Also**

* [Maildrop Quickstart](/quickstart)

### The full GraphQL schema for Maildrop

Taken directly from the source code for the API server:

```graphql
export const schema = `#graphql
    type Message {
        id: String
        ip: String
        helo: String
        date: String
        mailfrom: String
        rcptto: [String]
        headerfrom: String
        subject: String
        data: String
        html: String
    }
    type Statistics {
        blocked: Int
        saved: Int
    }
    type Query {
        ping(message: String): String
        inbox(mailbox: String!): [Message]
        message(mailbox: String!, id: String!): Message
        altinbox(mailbox: String!): String
        statistics: Statistics
        status: String
    }
    type Mutation {
        delete(mailbox: String!, id: String!): Boolean
    }
`;
```

#### **See Also**

* [GraphQL reference type for a Message](/graphql-types/message)
* [GraphQL reference type for the site Statistics](/graphql-types/statistics)


# Get a Mailbox Listing

This is the GraphQL query to run in order to get a list of all messages inside a mailbox.

{% hint style="warning" %}
**Please note** that the list of messages in the mailbox will come back with the "**data**" and "**html**" fields set to null. This is for performance reasons - returning 10 messages with 500k of data each would wind up with extremely slow mailbox listings. If you want to retrieve the data and html of a message, get the message id, and then [retrieve the specific message](/api-reference/get-a-specific-message).
{% endhint %}

## Gets an array of messages belonging to a mailbox.

<mark style="color:green;">`POST`</mark> `https://api.maildrop.cc/graphql`

This GraphQL query takes a mailbox and an id as required parameters. Returns an array of Message objects with the "data" and "html" fields set to null.

(GraphQL best practices discourage queries and variable names from being the same, so the query is named "inbox".)

#### Headers

| Name         | Type   | Description      |
| ------------ | ------ | ---------------- |
| Content-Type | String | application/json |

#### Request Body

| Name | Type   | Description                                                                                 |
| ---- | ------ | ------------------------------------------------------------------------------------------- |
|      | String | '{"query":"query Example { inbox(mailbox:\\"testing\\") { id headerfrom subject date } }"}' |

{% tabs %}
{% tab title="200: OK " %}

```json
{
    "data": {
        "inbox": [{
            "id": "AIm59ihdGy",
            "headerfrom": "test@test.com",
            "subject": "Testing!",
            "date": "2023-02-09T23:51:14.411Z"
        }]
    }
}
```

{% endtab %}
{% endtabs %}

#### See Also

* [GraphQL reference type for a Message](/graphql-types/message)

{% tabs %}
{% tab title="curl" %}

```bash
curl --request POST \
    --header 'content-type: application/json' \
    --url https://api.maildrop.cc/graphql \
    --data '{"query":"query Example { inbox(mailbox:\"testing\") { id headerfrom subject date } }"}'
```

returns:

```json
{"data":{"inbox":[{"id":"AIm59ihdGy","headerfrom":"test@heluna.com","subject":"test Thu, 09 Feb 2023 23:51:14 +0000","date":"2023-02-09T23:51:14.411Z"}]}}
```

{% endtab %}

{% tab title="React" %}

```tsx
export const GET_INBOX = gql`
    query GetInbox($mailbox: String!) {
        inbox(mailbox: $mailbox) {
            id
            subject
            date
            headerfrom
        }
    }
`;

interface QueryReturn {
    inbox: Message[];
}

interface MyComponentProps {
    mailbox: string;
}

const MyComponent = (props: MyComponentProps) => {
    const { loading, error, data } = useQuery<QueryReturn>(GET_INBOX, {
        variables: { mailbox: props.mailbox }
    });
    return (
        <div>
            {loading && <div>Loading...</div>}
            {!loading && error && <div>There was an error.</div>}
            {data?.inbox.map((message: Message) => (<div key={message.id}>{message.subject}</div>))}            
        </div>
    );
};
```

{% endtab %}
{% endtabs %}


# Get a Specific Message

This is the GraphQL query to run when you want to get the body and html of a particular message.

{% hint style="info" %}
This is the only GraphQL query that will allow you to get the raw body and the html of the message.
{% endhint %}

## Gets a specific message, by id, from a mailbox.

<mark style="color:green;">`POST`</mark> `https://api.maildrop.cc/graphql`

This GraphQL query takes a mailbox and an id as required parameters. Returns a Message object with valid "data" and "html" fields.

#### Headers

| Name         | Type   | Description      |
| ------------ | ------ | ---------------- |
| Content-Type | String | application/json |

#### Request Body

| Name | Type   | Description                                                                                                        |
| ---- | ------ | ------------------------------------------------------------------------------------------------------------------ |
|      | String | '{"query":"query Example { message(mailbox:\\"testing\\", id:\\"AIm59ihdGy\\") { id headerfrom subject date } }"}' |

{% tabs %}
{% tab title="200: OK " %}

<pre class="language-json"><code class="lang-json"><strong>{
</strong><strong>    "data": {
</strong><strong>        "message": {
</strong><strong>            "id": "AIm59ihdGy",
</strong><strong>            "headerfrom": "Test &#x3C;test@test.com>",
</strong><strong>            "subject": "Testing!",
</strong><strong>            "date": "2023-02-09T23:51:14.411Z"
</strong><strong>        }
</strong><strong>    }
</strong><strong>}
</strong></code></pre>

{% endtab %}
{% endtabs %}

#### See Also

* [GraphQL reference type for a Message](/graphql-types/message)

#### Examples

{% tabs %}
{% tab title="curl" %}

```bash
curl --request POST \
    --header 'content-type: application/json' \
    --url https://api.maildrop.cc/graphql \
    --data '{"query":"query Example {\n  message(mailbox:\"testing\", id:\"AIm59ihdGy\") { id headerfrom subject date }\n}"}'
```

returns:

```json
{"data":{"message":{"id":"AIm59ihdGy","headerfrom":"test@test.com","subject":"Testing!","date":"2023-02-09T23:51:14.411Z"}}}
```

{% endtab %}

{% tab title="React" %}

```tsx
export const GET_MESSAGE = gql`
    query GetMessage($mailbox: String!, $id: String!) {
        message(mailbox: $mailbox, id: $id) {
            id
            subject
            date
            headerfrom
            data
            html
        }
    }
`;

interface QueryReturn {
    message: Message;
}

interface MyComponentProps {
    mailbox: string;
    id: string;
}

const MyComponent = (props: MyComponentProps) => {
    const { loading, error, data } = useQuery<QueryReturn>(GET_MESSAGE, {
        variables: { mailbox: props.mailbox, id: props.id },
    });
    return (
        <div>
            {loading && <div>Loading...</div>}
            {!loading && error && <div>There was an error.</div>}
            {!loading && data?.message && <div>Message: {data.message.subject}</div>}            
        </div>
    );
};
```

{% endtab %}
{% endtabs %}


# Delete a Message

This is the GraphQL mutation to run when you want to delete a message from a mailbox.

### Do I need to delete messages from Maildrop?

In most cases, you shouldn't need to delete any messages. Mailboxes are temporary, and if no email messages are sent to a mailbox within 24 hours, the mailbox is completely erased automatically. Additionally, when there are a large amount of incoming messages, mailboxes that haven't seen messages recently may get emptied before the 24 hour window.

If you are sending a large number of automated messages (for example, testing sending out batches of messages to a large database of mock email addresses) then as a courtesy, you should delete those messages as part of your testing script cleanup phase.

## Deletes an individual message, by id, from a mailbox.

<mark style="color:green;">`POST`</mark> `https://api.maildrop.cc/graphql`

This GraphQL mutation takes a mailbox name and a message id as required parameters. This only returns a boolean of whether the message was deleted or not. Incorrect mailbox/id combinations will still return true.

#### Headers

| Name         | Type   | Description      |
| ------------ | ------ | ---------------- |
| Content-Type | String | application/json |

#### Request Body

| Name | Type   | Description                                                                       |
| ---- | ------ | --------------------------------------------------------------------------------- |
|      | String | '{"query":"mutation Example { delete(mailbox:\\"testing\\", id:\\"abc123\\") }"}' |

{% tabs %}
{% tab title="200: OK " %}

```json
{
    "data": {
        "delete": true
    }
}
```

{% endtab %}
{% endtabs %}

#### Examples

{% tabs %}
{% tab title="curl" %}

```bash
curl --request POST \
    --header 'content-type: application/json' \
    --url https://api.maildrop.cc/graphql \
    --data '{"query":"mutation Example { delete(mailbox:\"testing\", id:\"abc123\") }"}'
```

returns:

```json
{"data":{"delete":true}}
```

{% endtab %}

{% tab title="React" %}

```tsx
export const DELETE_MESSAGE = gql`
    mutation DeleteMessage($mailbox: String!, $id: String!) {
        delete(mailbox: $mailbox, id: $id)
    }
}`;

interface MutationReturn {
    delete: boolean;
}

interface MutationVariables {
    mailbox: string;
    id: string;
}

interface MyComponentProps {
    mailbox: string;
    id: string;
}

const MyComponent = (props: MyComponentProps) => {
    const [deleteMessage, { data, loading, error }] = useMutation<MutationReturn, MutationVariables>(DELETE_MESSAGE, {
        variables: { mailbox: props.mailbox, id: props.id }
    });
    return (
        <div>
            {loading && <div>Deleting...</div>}
            {!loading && <button onClick={deleteMessage}>Delete Message</button>}
            {!loading && error && <div>There was an error.</div>}
            {!loading && data?.delete && <div>Message deleted.</div>}            
        </div>
    );
};
```

{% endtab %}
{% endtabs %}


# Get a Mailbox Alias

This is the GraphQL query to run when you want to get the mailbox alias for a given mailbox.

### What's a Mailbox Alias?

Every email address on Maildrop has a corresponding "Mailbox Alias", which is an encoded two-way-hash of the email address itself, with the secret key for the hash known only to Maildrop.

This means, if you wanted to give someone the address "<myaddress@maildrop.cc>" but didn't want them to be able to go to the site and read that mailbox, you could give them the mailbox alias, for example "<D-1lfhru8dn@maildrop.cc>". Messages sent to this mailbox alias would still go to <myaddress@maildrop.cc> but the sender wouldn't know the true destination.

This serves as an additional layer of security if you're concerned about others getting access to the mailbox.

Each mailbox on the maildrop.cc site has this section which includes the mailbox alias:

<figure><img src="/files/Pwr70cNvwt2faMO05BXv" alt="A sample Maildrop alias address."><figcaption><p>From the maildrop.cc website</p></figcaption></figure>

{% hint style="info" %}
If you're using Maildrop in an automated fashion it's unlikely that you'll need to query for the mailbox alias - it's more useful for you to just create a unique address that only you know (for example, a uuidv4 address @ maildrop.cc).
{% endhint %}

## Gets the Mailbox Alias for a given mailbox.

<mark style="color:green;">`POST`</mark> `https://api.maildrop.cc/graphql`

Retrieves the Mailbox Alias for the address in the query. The query does not need to contain the entire email address, just the username portion. For example, "<test@maildrop.cc>" only needs "test" as the query parameter.

#### Headers

| Name         | Type   | Description      |
| ------------ | ------ | ---------------- |
| Content-Type | String | application/json |

#### Request Body

| Name | Type   | Description                                                        |
| ---- | ------ | ------------------------------------------------------------------ |
|      | String | '{"query":"query Example { altinbox(mailbox:\\"myusername\\") }"}' |

{% tabs %}
{% tab title="200: OK " %}

```json
{
    "data": {
        "altinbox": "D-1lp8kheq"
    }
}
```

{% endtab %}
{% endtabs %}

#### Examples

{% tabs %}
{% tab title="curl" %}

```bash
curl --request POST \
    --header 'content-type: application/json' \
    --url https://api.maildrop.cc/graphql \
    --data '{"query":"query Example {\n altinbox(mailbox:\"testing\") }"
```

returns:

```json
{"data":{"altinbox":"D-1lp8kheq"}}
```

{% endtab %}

{% tab title="React" %}

```tsx
export const GET_ALIAS = gql`
    query GetAlias($mailbox: String!) {
        altinbox(mailbox: $mailbox)
    }
}`;

interface QueryReturn {
    altinbox: string;
}

interface MyComponentProps {
    mailbox: string;
}

const MyComponent = (props: MyComponentProps) => {
    const [{ loading, error, data }] = useQuery<QueryReturn>(GET_ALIAS, {
        variables: { mailbox: props.mailbox },
    });
    return (
        <div>
            {loading && <div>Loading...</div>}
            {!loading && error && <div>There was an error.</div>}
            {!loading && data?.altinbox && <div>Mailbox Alias: {data.altinbox}@maildrop.cc</div>}            
        </div>
    );
};
```

{% endtab %}
{% endtabs %}


# Maildrop Statistics

This is the GraphQL query to run when you want to see overall statistics about Maildrop emails.

{% hint style="info" %}
This method is provided as a convenience method to show the current totals of blocked and saved messages. Most users should never need to run this query.
{% endhint %}

## Gets the current number of messages that have been blocked and messages that have been delivered to mailboxes.

<mark style="color:green;">`POST`</mark> `https://api.maildrop.cc/graphql`

Returns a JSON object that represents the total number of messages blocked by the Heluna antispam filters, and the total number of messages successfully delivered to mailboxes.&#x20;

Results are cached for up to a minute.

#### Headers

| Name         | Type   | Description      |
| ------------ | ------ | ---------------- |
| Content-Type | String | application/json |

#### Request Body

| Name | Type   | Description                                                   |
| ---- | ------ | ------------------------------------------------------------- |
|      | String | '{ query: "query Example { statistics { blocked saved } }" }' |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    "data": {
        "statistics": {
            "blocked": 123456789,
            "saved": 101010101
        }
    }
}
```

{% endtab %}
{% endtabs %}

#### Examples

{% tabs %}
{% tab title="curl" %}

```bash
curl --request POST \
    --header 'content-type: application/json' \
    --url https://api.maildrop.cc/graphql \
    --data '{"query":"query Example {\n  statistics { blocked saved }\n}"}'
```

returns:

```json
{"data":{"statistics":{"blocked":12345,"saved":67890}}}
```

{% endtab %}

{% tab title="React" %}

```tsx
export const GET_STATISTICS = gql`
    query GetStatistics {
        statistics {
            blocked
            saved
        }
    }
}`;

interface Statistics {
    blocked: number;
    saved: number;
}

interface QueryReturn {
    statistics: Statistics;
}

const MyComponent = () => {
    const [{ loading, error, data }] = useQuery<QueryReturn>(GET_STATISTICS);
    return (
        <div>
            {loading && <div>Loading...</div>}
            {!loading && error && <div>There was an error.</div>}
            {!loading && data?.statistics && <div>Statistics: {data.statistics.blocked} blocked / {data.statistics.saved} saved</div>}            
        </div>
    );
};
```

{% endtab %}
{% endtabs %}


# Service Status

This is the GraphQL query to run to return a simple boolean of whether Maildrop is functioning or not.

{% hint style="info" %}
There are multiple services that report their status; this method is provided as a convenience to see if Maildrop is completely functional or not. Most users should never need to run this query.
{% endhint %}

## Returns the status of Maildrop as a string.

<mark style="color:green;">`POST`</mark> `https://api.maildrop.cc/graphql`

Checks the current status of the various services in the Maildrop architecture and returns either "operational" or an error string.

Results are cached for up to a minute.

#### Headers

| Name         | Type   | Description      |
| ------------ | ------ | ---------------- |
| Content-Type | String | application/json |

#### Request Body

| Name | Type   | Description                             |
| ---- | ------ | --------------------------------------- |
|      | String | '{ query: "query Example { status }" }' |

{% tabs %}
{% tab title="200: OK " %}

```json
{
    "data": {
        "status": "operational"
    }
}
```

{% endtab %}
{% endtabs %}

#### Examples

{% tabs %}
{% tab title="curl" %}

```bash
curl --request POST \
    --header 'content-type: application/json' \
    --url https://api.maildrop.cc/graphql \
    --data '{"query":"query Example {\n  status\n}"}'
```

returns:

```json
{"data":{"status":"operational"}}
```

{% endtab %}

{% tab title="React" %}

```tsx
export const GET_STATUS = gql`
    query GetStatus {
        status
    }
}`;

interface QueryReturn {
    status: string;
}

const MyComponent = () => {
    const [{ loading, error, data }] = useQuery<QueryReturn>(GET_STATUS);
    return (
        <div>
            {loading && <div>Loading...</div>}
            {!loading && error && <div>There was an error.</div>}
            {!loading && data?.status && <div>Status: {data.status}</div>}            
        </div>
    );
};
```

{% endtab %}
{% endtabs %}


# Message

The GraphQL type definition for a Message returned by the API.

```graphql
type Message {
        id: String
        ip: String
        helo: String
        date: String
        mailfrom: String
        rcptto: [String]
        headerfrom: String
        subject: String
        data: String
        html: String
}
```

<table><thead><tr><th width="159">Field</th><th>Description</th></tr></thead><tbody><tr><td><strong>id</strong></td><td>A 10-character unique id for each message.</td></tr><tr><td><strong>ip</strong></td><td>The ip address of the originating mail server. This can be in either ipv4 or ipv6 format.</td></tr><tr><td><strong>helo</strong></td><td>The domain specified in the RFC 821 "HELO (domain)" SMTP greeting sent by the originating mail server.</td></tr><tr><td><strong>date</strong></td><td>An ISO-8601 compatible string representing the date the message was received by Maildrop.</td></tr><tr><td><strong>mailfrom</strong></td><td>The email address specified in the RFC 821 "MAIL FROM:&#x3C;address@domain.com>" SMTP sender sent by the originating mail server.</td></tr><tr><td><strong>rcptto</strong></td><td>An array of destination addresses specified in the RFC 821 "RCPT TO:&#x3C;destination@you.com>" SMTP recipient sent by the originating mail server.</td></tr><tr><td><strong>headerfrom</strong></td><td>The contents of the "From:" header in the email message.</td></tr><tr><td><strong>subject</strong></td><td>The contents of the "Subject:" header in the email message.</td></tr><tr><td><strong>data</strong></td><td>The raw SMTP email message sent to Maildrop.</td></tr><tr><td><strong>html</strong></td><td>If the message contained a MIME multipart html, that html data is here, otherwise this field contains the plain text body of the message.</td></tr></tbody></table>

{% hint style="danger" %}
**Note**: The **data** and **html** fields are only available when you are querying [a specific message](/api-reference/get-a-specific-message). For performance reasons, you should get the listing of messages, then retrieve the messages you're looking for one at a time.
{% endhint %}


# Statistics

The GraphQL type definition for the Maildrop Statistics returned by the API.

```graphql
type Statistics {
        blocked: Int
        saved: Int
}
```

<table><thead><tr><th width="148">Field</th><th>Description</th></tr></thead><tbody><tr><td><strong>blocked</strong></td><td>The number of messages that the Heluna antispam filters have blocked for Maildrop.</td></tr><tr><td><strong>saved</strong></td><td>The number of clean messages that have been delivered to Maildrop mailboxes.</td></tr></tbody></table>

{% hint style="info" %}
These statistics may be cached for up to a minute and may not reflect the current true totals.
{% endhint %}


