Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.14.0"
".": "0.15.0"
}
6 changes: 3 additions & 3 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 94
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/agentmail/agentmail-ec4e26c46715d10a0de953666e890ab67f97e61f7355971ed728942f957100f8.yml
openapi_spec_hash: 74a582c32cd3a4f6e2afb1e84eccbb21
config_hash: 8ab5eb1bfc282411f0283d386a319f23
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/agentmail/agentmail-f4753a92b17ddb79cf8082f675b8ef761b0f616d4fec4ae77e6097a72ca2b9d5.yml
openapi_spec_hash: d5a93e3167c99d7b144314e0d11835b3
config_hash: 79c13cf7727d64173933e0d367570632
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## 0.15.0 (2026-05-30)

Full Changelog: [v0.14.0...v0.15.0](https://github.com/agentmail-to/agentmail-go/compare/v0.14.0...v0.15.0)

### Features

* **api:** api update ([c063bef](https://github.com/agentmail-to/agentmail-go/commit/c063befb1ea48ab781cf1a591bad18dc4ca32bf0))
* **api:** api update ([25e6ee7](https://github.com/agentmail-to/agentmail-go/commit/25e6ee7de1c451a47316e426a21c135fd89e07fe))
* **api:** api update ([27e9374](https://github.com/agentmail-to/agentmail-go/commit/27e93742f95d6023129b15c14d7084dae7936fbe))
* **api:** api update ([d915d4b](https://github.com/agentmail-to/agentmail-go/commit/d915d4bca3c61f4891b8bc4e947469c0462ad922))
* **api:** api update ([c1a4c8c](https://github.com/agentmail-to/agentmail-go/commit/c1a4c8cd89313015584e5546fb04c0ca72fb1d9b))

## 0.14.0 (2026-05-14)

Full Changelog: [v0.13.0...v0.14.0](https://github.com/agentmail-to/agentmail-go/compare/v0.13.0...v0.14.0)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Or to pin the version:
<!-- x-release-please-start-version -->

```sh
go get -u 'github.com/agentmail-to/agentmail-go@v0.14.0'
go get -u 'github.com/agentmail-to/agentmail-go@v0.15.0'
```

<!-- x-release-please-end -->
Expand Down
5 changes: 4 additions & 1 deletion agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ func (r *AgentService) SignUp(ctx context.Context, body AgentSignUpParams, opts
// `agent_verified`, the send allowlist is removed, and free plan entitlements are
// applied.
//
// The OTP expires after 24 hours and allows a maximum of 10 attempts.
// The OTP expires after 24 hours and allows a maximum of 10 attempts. If you run
// into any difficulties receiving the OTP code, you can also create an account on
// [console.agentmail.to](https://console.agentmail.to) using the human email
// address you provided to verify your account.
//
// **CLI:**
//
Expand Down
92 changes: 91 additions & 1 deletion inbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package agentmail

import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
Expand Down Expand Up @@ -153,6 +154,8 @@ type CreateInboxParam struct {
Domain param.Opt[string] `json:"domain,omitzero"`
// Username of address. Randomly generated if not specified.
Username param.Opt[string] `json:"username,omitzero"`
// Custom metadata to attach to the inbox.
Metadata map[string]CreateInboxMetadataUnionParam `json:"metadata,omitzero"`
paramObj
}

Expand All @@ -164,6 +167,23 @@ func (r *CreateInboxParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

// Only one field can be non-zero.
//
// Use [param.IsOmitted] to confirm if a field is set.
type CreateInboxMetadataUnionParam struct {
OfString param.Opt[string] `json:",omitzero,inline"`
OfFloat param.Opt[float64] `json:",omitzero,inline"`
OfBool param.Opt[bool] `json:",omitzero,inline"`
paramUnion
}

func (u CreateInboxMetadataUnionParam) MarshalJSON() ([]byte, error) {
return param.MarshalUnion(u, u.OfString, u.OfFloat, u.OfBool)
}
func (u *CreateInboxMetadataUnionParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, u)
}

type Inbox struct {
// Time at which inbox was created.
CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"`
Expand All @@ -179,6 +199,8 @@ type Inbox struct {
ClientID string `json:"client_id" api:"nullable"`
// Display name: `Display Name <username@domain.com>`.
DisplayName string `json:"display_name" api:"nullable"`
// Custom metadata attached to the inbox.
Metadata map[string]InboxMetadataUnion `json:"metadata" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
CreatedAt respjson.Field
Expand All @@ -188,6 +210,7 @@ type Inbox struct {
UpdatedAt respjson.Field
ClientID respjson.Field
DisplayName respjson.Field
Metadata respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
Expand All @@ -199,6 +222,50 @@ func (r *Inbox) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

// InboxMetadataUnion contains all possible properties and values from [string],
// [float64], [bool].
//
// Use the methods beginning with 'As' to cast the union to one of its variants.
//
// If the underlying value is not a json object, one of the following properties
// will be valid: OfString OfFloat OfBool]
type InboxMetadataUnion struct {
// This field will be present if the value is a [string] instead of an object.
OfString string `json:",inline"`
// This field will be present if the value is a [float64] instead of an object.
OfFloat float64 `json:",inline"`
// This field will be present if the value is a [bool] instead of an object.
OfBool bool `json:",inline"`
JSON struct {
OfString respjson.Field
OfFloat respjson.Field
OfBool respjson.Field
raw string
} `json:"-"`
}

func (u InboxMetadataUnion) AsString() (v string) {
apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
return
}

func (u InboxMetadataUnion) AsFloat() (v float64) {
apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
return
}

func (u InboxMetadataUnion) AsBool() (v bool) {
apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
return
}

// Returns the unmodified JSON received from the API
func (u InboxMetadataUnion) RawJSON() string { return u.JSON.raw }

func (r *InboxMetadataUnion) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

type ListInboxes struct {
// Number of items returned.
Count int64 `json:"count" api:"required"`
Expand Down Expand Up @@ -274,7 +341,13 @@ func (r *InboxNewParams) UnmarshalJSON(data []byte) error {

type InboxUpdateParams struct {
// Display name: `Display Name <username@domain.com>`.
DisplayName string `json:"display_name" api:"required"`
DisplayName param.Opt[string] `json:"display_name,omitzero"`
// Metadata to merge into the inbox's existing metadata. Keys you include are added
// or overwritten; keys you omit are left unchanged. To remove a single key, send
// it with a null value. To clear all metadata, send `metadata` as null. Sending an
// empty object is rejected; use null to clear. Each update must include at least
// one of `display_name` or `metadata`.
Metadata map[string]InboxUpdateParamsMetadataUnion `json:"metadata,omitzero"`
paramObj
}

Expand All @@ -286,6 +359,23 @@ func (r *InboxUpdateParams) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

// Only one field can be non-zero.
//
// Use [param.IsOmitted] to confirm if a field is set.
type InboxUpdateParamsMetadataUnion struct {
OfString param.Opt[string] `json:",omitzero,inline"`
OfFloat param.Opt[float64] `json:",omitzero,inline"`
OfBool param.Opt[bool] `json:",omitzero,inline"`
paramUnion
}

func (u InboxUpdateParamsMetadataUnion) MarshalJSON() ([]byte, error) {
return param.MarshalUnion(u, u.OfString, u.OfFloat, u.OfBool)
}
func (u *InboxUpdateParamsMetadataUnion) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, u)
}

type InboxListParams struct {
// Sort in ascending temporal order.
Ascending param.Opt[bool] `query:"ascending,omitzero" json:"-"`
Expand Down
16 changes: 13 additions & 3 deletions inbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ func TestInboxNewWithOptionalParams(t *testing.T) {
ClientID: agentmail.String("client_id"),
DisplayName: agentmail.String("display_name"),
Domain: agentmail.String("domain"),
Username: agentmail.String("username"),
Metadata: map[string]agentmail.CreateInboxMetadataUnionParam{
"foo": {
OfString: agentmail.String("string"),
},
},
Username: agentmail.String("username"),
},
})
if err != nil {
Expand All @@ -44,7 +49,7 @@ func TestInboxNewWithOptionalParams(t *testing.T) {
}
}

func TestInboxUpdate(t *testing.T) {
func TestInboxUpdateWithOptionalParams(t *testing.T) {
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
Expand All @@ -61,7 +66,12 @@ func TestInboxUpdate(t *testing.T) {
context.TODO(),
"inbox_id",
agentmail.InboxUpdateParams{
DisplayName: "display_name",
DisplayName: agentmail.String("display_name"),
Metadata: map[string]agentmail.InboxUpdateParamsMetadataUnion{
"foo": {
OfString: agentmail.String("string"),
},
},
},
)
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions inboxlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ type InboxListNewResponse struct {
PodID string `json:"pod_id" api:"required"`
// ID of inbox, if entry is inbox-scoped.
InboxID string `json:"inbox_id" api:"nullable"`
// Whether the entry is read-only and cannot be deleted via the API.
ReadOnly bool `json:"read_only" api:"nullable"`
// Reason for adding the entry.
Reason string `json:"reason" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
Expand All @@ -150,6 +152,7 @@ type InboxListNewResponse struct {
OrganizationID respjson.Field
PodID respjson.Field
InboxID respjson.Field
ReadOnly respjson.Field
Reason respjson.Field
ExtraFields map[string]respjson.Field
raw string
Expand Down Expand Up @@ -236,6 +239,8 @@ type InboxListListResponseEntry struct {
PodID string `json:"pod_id" api:"required"`
// ID of inbox, if entry is inbox-scoped.
InboxID string `json:"inbox_id" api:"nullable"`
// Whether the entry is read-only and cannot be deleted via the API.
ReadOnly bool `json:"read_only" api:"nullable"`
// Reason for adding the entry.
Reason string `json:"reason" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
Expand All @@ -248,6 +253,7 @@ type InboxListListResponseEntry struct {
OrganizationID respjson.Field
PodID respjson.Field
InboxID respjson.Field
ReadOnly respjson.Field
Reason respjson.Field
ExtraFields map[string]respjson.Field
raw string
Expand Down Expand Up @@ -283,6 +289,8 @@ type InboxListGetResponse struct {
PodID string `json:"pod_id" api:"required"`
// ID of inbox, if entry is inbox-scoped.
InboxID string `json:"inbox_id" api:"nullable"`
// Whether the entry is read-only and cannot be deleted via the API.
ReadOnly bool `json:"read_only" api:"nullable"`
// Reason for adding the entry.
Reason string `json:"reason" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
Expand All @@ -295,6 +303,7 @@ type InboxListGetResponse struct {
OrganizationID respjson.Field
PodID respjson.Field
InboxID respjson.Field
ReadOnly respjson.Field
Reason respjson.Field
ExtraFields map[string]respjson.Field
raw string
Expand Down
2 changes: 1 addition & 1 deletion internal/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

package internal

const PackageVersion = "0.14.0" // x-release-please-version
const PackageVersion = "0.15.0" // x-release-please-version
9 changes: 9 additions & 0 deletions list.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ type ListNewResponse struct {
ListType ListNewResponseListType `json:"list_type" api:"required"`
// ID of organization.
OrganizationID string `json:"organization_id" api:"required"`
// Whether the entry is read-only and cannot be deleted via the API.
ReadOnly bool `json:"read_only" api:"nullable"`
// Reason for adding the entry.
Reason string `json:"reason" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
Expand All @@ -128,6 +130,7 @@ type ListNewResponse struct {
EntryType respjson.Field
ListType respjson.Field
OrganizationID respjson.Field
ReadOnly respjson.Field
Reason respjson.Field
ExtraFields map[string]respjson.Field
raw string
Expand Down Expand Up @@ -210,6 +213,8 @@ type ListListResponseEntry struct {
ListType string `json:"list_type" api:"required"`
// ID of organization.
OrganizationID string `json:"organization_id" api:"required"`
// Whether the entry is read-only and cannot be deleted via the API.
ReadOnly bool `json:"read_only" api:"nullable"`
// Reason for adding the entry.
Reason string `json:"reason" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
Expand All @@ -220,6 +225,7 @@ type ListListResponseEntry struct {
EntryType respjson.Field
ListType respjson.Field
OrganizationID respjson.Field
ReadOnly respjson.Field
Reason respjson.Field
ExtraFields map[string]respjson.Field
raw string
Expand Down Expand Up @@ -251,6 +257,8 @@ type ListGetResponse struct {
ListType ListGetResponseListType `json:"list_type" api:"required"`
// ID of organization.
OrganizationID string `json:"organization_id" api:"required"`
// Whether the entry is read-only and cannot be deleted via the API.
ReadOnly bool `json:"read_only" api:"nullable"`
// Reason for adding the entry.
Reason string `json:"reason" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
Expand All @@ -261,6 +269,7 @@ type ListGetResponse struct {
EntryType respjson.Field
ListType respjson.Field
OrganizationID respjson.Field
ReadOnly respjson.Field
Reason respjson.Field
ExtraFields map[string]respjson.Field
raw string
Expand Down
25 changes: 24 additions & 1 deletion podinbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,13 @@ type PodInboxUpdateParams struct {
// ID of pod.
PodID string `path:"pod_id" api:"required" json:"-"`
// Display name: `Display Name <username@domain.com>`.
DisplayName string `json:"display_name" api:"required"`
DisplayName param.Opt[string] `json:"display_name,omitzero"`
// Metadata to merge into the inbox's existing metadata. Keys you include are added
// or overwritten; keys you omit are left unchanged. To remove a single key, send
// it with a null value. To clear all metadata, send `metadata` as null. Sending an
// empty object is rejected; use null to clear. Each update must include at least
// one of `display_name` or `metadata`.
Metadata map[string]PodInboxUpdateParamsMetadataUnion `json:"metadata,omitzero"`
paramObj
}

Expand All @@ -163,6 +169,23 @@ func (r *PodInboxUpdateParams) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

// Only one field can be non-zero.
//
// Use [param.IsOmitted] to confirm if a field is set.
type PodInboxUpdateParamsMetadataUnion struct {
OfString param.Opt[string] `json:",omitzero,inline"`
OfFloat param.Opt[float64] `json:",omitzero,inline"`
OfBool param.Opt[bool] `json:",omitzero,inline"`
paramUnion
}

func (u PodInboxUpdateParamsMetadataUnion) MarshalJSON() ([]byte, error) {
return param.MarshalUnion(u, u.OfString, u.OfFloat, u.OfBool)
}
func (u *PodInboxUpdateParamsMetadataUnion) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, u)
}

type PodInboxListParams struct {
// Sort in ascending temporal order.
Ascending param.Opt[bool] `query:"ascending,omitzero" json:"-"`
Expand Down
Loading
Loading