Retrieve a sending address

Add MCP server to your AI tool

Allow AI tools and LLMs to interact with the API documentation portal through MCP.

MCP server URL

https://api-reference.usecommune.dev/mcp

Standard setup for AI tools providing an mcp.json file

mcp.json
{
  "REST API MCP server": {
    "url": "https://api-reference.usecommune.dev/mcp"
  }
}

Close
GET /senders/{sender}

Read one sending address, including the DNS records the creator has to publish and the reason verification last failed. Creator scope.

Headers

  • Commune-Version string(date)

    The contract version this request is written against, as a release date (YYYY-MM-DD). Omitting the header pins the request to the version that was current when the API key was issued, so an integration keeps working when a newer version ships. An unknown value answers 400 with invalid_version.

Path parameters

  • sender string(uuid) Required

    The sending address's id. It has no short id.

Query parameters

  • expand string

    Comma separated list of relationship paths to inline in the response. Unexpanded relationships are returned as a reference object carrying only id and object. Each operation documents the paths it accepts, and an unknown path answers 400. Nested paths use a dot, for example article.newsletter.

    One accepted path is not a relationship. ?expand=content on GET /articles/{article} adds the Markdown rendition of the body beside the HTML one. It is the same trade the parameter always offers, a fuller response for a larger one, over a property that has more than one representation rather than over a reference.

  • fields string

    Comma separated allow list of top level properties to return on each object, so a client can trim a response it does not need in full. id and object are always returned. An unknown property name answers 400. Properties omitted by an operation, such as content on any article list, cannot be brought back with fields.

    A trimmed body is a subset of the schema this operation declares, and a property that schema marks required is absent when it was not asked for. That is the point of the parameter, so a client that validates responses against the schema either sends no fields or relaxes required.

Responses

  • 200 application/json

    The sending address.

    Hide response attributes Show response attributes object
    • object string Required

      Always sender.

      Value is sender.

    • id string(uuid) Required

      Stable identifier.

    • newsletter object | null Required

      The newsletter that sends from this address. A Ref unless newsletter is named in ?expand=.

      One of:
    • kind string Required

      native is an address Commune provisioned on a domain it owns, which works without the creator touching DNS. custom is an address on the creator's own domain, which does not work until they publish the records.

      Values are native or custom.

    • from_email string(email) Required

      The full address issues are sent from.

    • from_name string | null

      The display name shown beside the address in an inbox.

    • reply_to_email string(email) | null

      Where replies go, when the creator wants them somewhere other than from_email.

    • domain string

      The domain part of the address.

    • local_part string

      The part before the at sign.

    • verification_status string Required

      How far along the address is. Only verified can send. provisioning means Commune is still setting it up and the creator has nothing to do yet.

      Values are provisioning, pending, verified, or failed.

    • verification_records array[object]

      The DNS records the creator must publish. Empty for a native address, where Commune owns the domain and has already done it.

      Hide verification_records attributes Show verification_records attributes object

      A record the creator has to publish in their own DNS before Commune can send from an address or serve a domain. These are public by nature: they end up in a zone anyone can query.

      • type string Required

        The record type.

      • name string Required

        The host the record goes on.

      • value string Required

        What the record must resolve to.

      • priority integer | null

        Priority, for a record type that takes one. Null otherwise.

      • status string | null

        What Commune last observed for this record, when it checked it individually. Null when only the address as a whole was checked.

    • verification_error string | null

      Why verification last failed, in a form the creator can act on. Null when it has not failed.

    • is_default boolean Required

      Whether this is the address the newsletter sends from unless told otherwise. Exactly one address per newsletter has this.

    • verified_at string(date-time) | null

      When the address was first verified. Null if it never was.

    • last_checked_at string(date-time) | null

      When Commune last looked at the DNS. Verification is re checked on a schedule, so this moves without the creator doing anything.

    • created_at string(date-time) Required

      When the address was added.

    • updated_at string(date-time)

      When the row last changed.

  • 400 application/json

    The request was malformed: an unknown query parameter, an unparseable cursor, an unknown expand path, or an unrecognised Commune-Version.

    Hide response attribute Show response attribute object
    • error object Required

      Additional properties are NOT allowed.

      Hide error attributes Show error attributes object
      • code string Required

        The stable, machine readable reason a request failed. New codes may be added in a minor version, so treat an unrecognised code as a generic failure of its HTTP status class.

        Values are bad_request, invalid_version, unauthorized, forbidden, insufficient_scope, payment_required, not_found, conflict, unprocessable, rate_limited, or internal_error.

      • message string Required

        A human readable sentence describing what went wrong. Written for a developer reading a log, not for an end user. Do not branch on it, branch on code.

      • param string

        The query, path or body parameter the error is attributed to, when the error is attributable to exactly one. Absent otherwise.

      • allowed_values array[string]

        Everything param would have accepted, when what it accepts is a finite set. Absent when it is not: a cursor, an identifier or a numeric range has nothing to enumerate, and an empty array would read as "nothing is allowed".

        It is deliberately redundant with message, which names the same values in prose. The array is what a program branches on and the sentence is what a model reads, and a caller correcting a request has to be able to do it from this one response without opening a reference page.

        On an unknown parameter name rather than an unknown value, this carries the parameter names the operation does accept, since that is the set the caller has to pick from.

        On an insufficient_scope failure there is no parameter at fault and param is absent, and this carries the scopes that would have been accepted instead.

      • request_id string

        Identifier for this request, echoed in the Commune-Request-Id response header. Quote it in support requests.

      • docs_url string(uri)

        Link to the reference page for this error code.

  • 401 application/json

    No API key was presented, or the key is unknown, revoked or expired.

    All four answer identically, down to the wording. Saying that a key was revoked rather than never issued confirms to whoever is holding the string that it was once real, which a legitimate caller does not need and a thief should not get.

    Hide headers attribute Show headers attribute
    • WWW-Authenticate string

      The authentication scheme this API accepts. Always Bearer realm="Commune API"; there is no second scheme and no query-parameter fallback, because a credential that can travel in a URL ends up in access logs and referer headers.

    Hide response attribute Show response attribute object
    • error object Required

      Additional properties are NOT allowed.

      Hide error attributes Show error attributes object
      • code string Required

        The stable, machine readable reason a request failed. New codes may be added in a minor version, so treat an unrecognised code as a generic failure of its HTTP status class.

        Values are bad_request, invalid_version, unauthorized, forbidden, insufficient_scope, payment_required, not_found, conflict, unprocessable, rate_limited, or internal_error.

      • message string Required

        A human readable sentence describing what went wrong. Written for a developer reading a log, not for an end user. Do not branch on it, branch on code.

      • param string

        The query, path or body parameter the error is attributed to, when the error is attributable to exactly one. Absent otherwise.

      • allowed_values array[string]

        Everything param would have accepted, when what it accepts is a finite set. Absent when it is not: a cursor, an identifier or a numeric range has nothing to enumerate, and an empty array would read as "nothing is allowed".

        It is deliberately redundant with message, which names the same values in prose. The array is what a program branches on and the sentence is what a model reads, and a caller correcting a request has to be able to do it from this one response without opening a reference page.

        On an unknown parameter name rather than an unknown value, this carries the parameter names the operation does accept, since that is the set the caller has to pick from.

        On an insufficient_scope failure there is no parameter at fault and param is absent, and this carries the scopes that would have been accepted instead.

      • request_id string

        Identifier for this request, echoed in the Commune-Request-Id response header. Quote it in support requests.

      • docs_url string(uri)

        Link to the reference page for this error code.

  • 403 application/json

    The key is valid but is not allowed to read this. Either it carries public scope and the operation needs creator scope, or it is bound to a different newsletter than the one addressed.

    Hide response attribute Show response attribute object
    • error object Required

      Additional properties are NOT allowed.

      Hide error attributes Show error attributes object
      • code string Required

        The stable, machine readable reason a request failed. New codes may be added in a minor version, so treat an unrecognised code as a generic failure of its HTTP status class.

        Values are bad_request, invalid_version, unauthorized, forbidden, insufficient_scope, payment_required, not_found, conflict, unprocessable, rate_limited, or internal_error.

      • message string Required

        A human readable sentence describing what went wrong. Written for a developer reading a log, not for an end user. Do not branch on it, branch on code.

      • param string

        The query, path or body parameter the error is attributed to, when the error is attributable to exactly one. Absent otherwise.

      • allowed_values array[string]

        Everything param would have accepted, when what it accepts is a finite set. Absent when it is not: a cursor, an identifier or a numeric range has nothing to enumerate, and an empty array would read as "nothing is allowed".

        It is deliberately redundant with message, which names the same values in prose. The array is what a program branches on and the sentence is what a model reads, and a caller correcting a request has to be able to do it from this one response without opening a reference page.

        On an unknown parameter name rather than an unknown value, this carries the parameter names the operation does accept, since that is the set the caller has to pick from.

        On an insufficient_scope failure there is no parameter at fault and param is absent, and this carries the scopes that would have been accepted instead.

      • request_id string

        Identifier for this request, echoed in the Commune-Request-Id response header. Quote it in support requests.

      • docs_url string(uri)

        Link to the reference page for this error code.

  • 404 application/json

    No such resource, or the key is not allowed to know that it exists. Commune answers 404 rather than 403 where distinguishing the two would leak the existence of private content.

    Hide response attribute Show response attribute object
    • error object Required

      Additional properties are NOT allowed.

      Hide error attributes Show error attributes object
      • code string Required

        The stable, machine readable reason a request failed. New codes may be added in a minor version, so treat an unrecognised code as a generic failure of its HTTP status class.

        Values are bad_request, invalid_version, unauthorized, forbidden, insufficient_scope, payment_required, not_found, conflict, unprocessable, rate_limited, or internal_error.

      • message string Required

        A human readable sentence describing what went wrong. Written for a developer reading a log, not for an end user. Do not branch on it, branch on code.

      • param string

        The query, path or body parameter the error is attributed to, when the error is attributable to exactly one. Absent otherwise.

      • allowed_values array[string]

        Everything param would have accepted, when what it accepts is a finite set. Absent when it is not: a cursor, an identifier or a numeric range has nothing to enumerate, and an empty array would read as "nothing is allowed".

        It is deliberately redundant with message, which names the same values in prose. The array is what a program branches on and the sentence is what a model reads, and a caller correcting a request has to be able to do it from this one response without opening a reference page.

        On an unknown parameter name rather than an unknown value, this carries the parameter names the operation does accept, since that is the set the caller has to pick from.

        On an insufficient_scope failure there is no parameter at fault and param is absent, and this carries the scopes that would have been accepted instead.

      • request_id string

        Identifier for this request, echoed in the Commune-Request-Id response header. Quote it in support requests.

      • docs_url string(uri)

        Link to the reference page for this error code.

  • 429 application/json

    Too many requests. Back off and retry after the interval named by the Retry-After response header.

    Hide headers attribute Show headers attribute
    • Retry-After integer

      Seconds to wait before retrying.

      Minimum value is 1.

    Hide response attribute Show response attribute object
    • error object Required

      Additional properties are NOT allowed.

      Hide error attributes Show error attributes object
      • code string Required

        The stable, machine readable reason a request failed. New codes may be added in a minor version, so treat an unrecognised code as a generic failure of its HTTP status class.

        Values are bad_request, invalid_version, unauthorized, forbidden, insufficient_scope, payment_required, not_found, conflict, unprocessable, rate_limited, or internal_error.

      • message string Required

        A human readable sentence describing what went wrong. Written for a developer reading a log, not for an end user. Do not branch on it, branch on code.

      • param string

        The query, path or body parameter the error is attributed to, when the error is attributable to exactly one. Absent otherwise.

      • allowed_values array[string]

        Everything param would have accepted, when what it accepts is a finite set. Absent when it is not: a cursor, an identifier or a numeric range has nothing to enumerate, and an empty array would read as "nothing is allowed".

        It is deliberately redundant with message, which names the same values in prose. The array is what a program branches on and the sentence is what a model reads, and a caller correcting a request has to be able to do it from this one response without opening a reference page.

        On an unknown parameter name rather than an unknown value, this carries the parameter names the operation does accept, since that is the set the caller has to pick from.

        On an insufficient_scope failure there is no parameter at fault and param is absent, and this carries the scopes that would have been accepted instead.

      • request_id string

        Identifier for this request, echoed in the Commune-Request-Id response header. Quote it in support requests.

      • docs_url string(uri)

        Link to the reference page for this error code.

  • 500 application/json

    Something failed inside Commune. The request may be retried.

    Hide response attribute Show response attribute object
    • error object Required

      Additional properties are NOT allowed.

      Hide error attributes Show error attributes object
      • code string Required

        The stable, machine readable reason a request failed. New codes may be added in a minor version, so treat an unrecognised code as a generic failure of its HTTP status class.

        Values are bad_request, invalid_version, unauthorized, forbidden, insufficient_scope, payment_required, not_found, conflict, unprocessable, rate_limited, or internal_error.

      • message string Required

        A human readable sentence describing what went wrong. Written for a developer reading a log, not for an end user. Do not branch on it, branch on code.

      • param string

        The query, path or body parameter the error is attributed to, when the error is attributable to exactly one. Absent otherwise.

      • allowed_values array[string]

        Everything param would have accepted, when what it accepts is a finite set. Absent when it is not: a cursor, an identifier or a numeric range has nothing to enumerate, and an empty array would read as "nothing is allowed".

        It is deliberately redundant with message, which names the same values in prose. The array is what a program branches on and the sentence is what a model reads, and a caller correcting a request has to be able to do it from this one response without opening a reference page.

        On an unknown parameter name rather than an unknown value, this carries the parameter names the operation does accept, since that is the set the caller has to pick from.

        On an insufficient_scope failure there is no parameter at fault and param is absent, and this carries the scopes that would have been accepted instead.

      • request_id string

        Identifier for this request, echoed in the Commune-Request-Id response header. Quote it in support requests.

      • docs_url string(uri)

        Link to the reference page for this error code.

GET /senders/{sender}
curl https://api.usecommune.com/senders/2f8b0c1a-5d34-4e7b-8f21-6a9c4b3d2e10 \
  -H "Authorization: Bearer $COMMUNE_API_KEY" \
  -H "Commune-Version: 2026-08-26"
curl \
 --request GET 'https://api.usecommune.com/senders/{sender}' \
 --header "Authorization: Bearer $ACCESS_TOKEN" \
 --header "Commune-Version: 2026-08-26"
Response examples (200)
{
  "object": "sender",
  "id": "string",
  "newsletter": {
    "object": "newsletter",
    "id": "9a4c1c6e-0f2b-4f47-9d3f-6d1b1a2c3d4e"
  },
  "kind": "native",
  "from_email": "hello@example.com",
  "from_name": "string",
  "reply_to_email": "hello@example.com",
  "domain": "string",
  "local_part": "string",
  "verification_status": "provisioning",
  "verification_records": [
    {
      "type": "CNAME",
      "name": "mail._domainkey.example.org",
      "value": "string",
      "priority": 42,
      "status": "string"
    }
  ],
  "verification_error": "string",
  "is_default": true,
  "verified_at": "2026-05-04T09:42:00Z",
  "last_checked_at": "2026-05-04T09:42:00Z",
  "created_at": "2026-05-04T09:42:00Z",
  "updated_at": "2026-05-04T09:42:00Z"
}
Response examples (400)
{
  "error": {
    "code": "bad_request",
    "message": "Newsletter not found.",
    "param": "cursor",
    "allowed_values": [
      "subscribed",
      "unsubscribed",
      "bounced",
      "complained",
      "pending"
    ],
    "request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
    "docs_url": "https://usecommune.com/docs/api/errors#not_found"
  }
}
Response examples (401)
# Headers
WWW-Authenticate: string

# Payload
{
  "error": {
    "code": "bad_request",
    "message": "Newsletter not found.",
    "param": "cursor",
    "allowed_values": [
      "subscribed",
      "unsubscribed",
      "bounced",
      "complained",
      "pending"
    ],
    "request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
    "docs_url": "https://usecommune.com/docs/api/errors#not_found"
  }
}
Response examples (403)
{
  "error": {
    "code": "bad_request",
    "message": "Newsletter not found.",
    "param": "cursor",
    "allowed_values": [
      "subscribed",
      "unsubscribed",
      "bounced",
      "complained",
      "pending"
    ],
    "request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
    "docs_url": "https://usecommune.com/docs/api/errors#not_found"
  }
}
Response examples (404)
{
  "error": {
    "code": "bad_request",
    "message": "Newsletter not found.",
    "param": "cursor",
    "allowed_values": [
      "subscribed",
      "unsubscribed",
      "bounced",
      "complained",
      "pending"
    ],
    "request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
    "docs_url": "https://usecommune.com/docs/api/errors#not_found"
  }
}
Response examples (429)
# Headers
Retry-After: 42

# Payload
{
  "error": {
    "code": "bad_request",
    "message": "Newsletter not found.",
    "param": "cursor",
    "allowed_values": [
      "subscribed",
      "unsubscribed",
      "bounced",
      "complained",
      "pending"
    ],
    "request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
    "docs_url": "https://usecommune.com/docs/api/errors#not_found"
  }
}
Response examples (500)
{
  "error": {
    "code": "bad_request",
    "message": "Newsletter not found.",
    "param": "cursor",
    "allowed_values": [
      "subscribed",
      "unsubscribed",
      "bounced",
      "complained",
      "pending"
    ],
    "request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
    "docs_url": "https://usecommune.com/docs/api/errors#not_found"
  }
}