openapi: 3.0.3 info: title: 'Postmaster+ API Documentation' description: '' version: 1.0.0 servers: - url: 'https://postmasterplus.app' tags: - name: Domains description: '' - name: IPs description: '' - name: Intelligence description: '' - name: Blocklists description: '' - name: Seedbox description: '' - name: 'Spam Identifiers' description: '' - name: Tools description: '' components: securitySchemes: default: type: http scheme: bearer description: 'You can retrieve your token by visiting your dashboard and clicking Team Settings > API Tokens.' security: - default: [] paths: /api/v1/domains: get: summary: 'Retrieve Domains.' operationId: retrieveDomains description: '' parameters: - in: query name: page description: 'The page number. Must be at least 1.' example: 1 required: false schema: type: integer description: 'The page number. Must be at least 1.' example: 1 - in: query name: per_page description: 'The number of domains per page. Must be at least 1. Must not be greater than 100.' example: 15 required: false schema: type: integer description: 'The number of domains per page. Must be at least 1. Must not be greater than 100.' example: 15 responses: 200: description: '' content: application/json: schema: type: object example: success: true message: 'Domains retrieved successfully.' data: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: example.com description: 'Primary sending domain' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' meta: current_page: 1 from: 1 last_page: 1 per_page: 15 to: 1 total: 1 properties: success: type: boolean example: true message: type: string example: 'Domains retrieved successfully.' data: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: example.com description: 'Primary sending domain' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: type: string example: example.com description: type: string example: 'Primary sending domain' created_at: type: string example: '2026-03-28T10:30:00.000000Z' updated_at: type: string example: '2026-03-28T10:30:00.000000Z' meta: type: object properties: current_page: type: integer example: 1 from: type: integer example: 1 last_page: type: integer example: 1 per_page: type: integer example: 15 to: type: integer example: 1 total: type: integer example: 1 tags: - Domains '/api/v1/domains/{id}/feed': get: summary: 'Retrieve Domain Feed.' operationId: retrieveDomainFeed description: '' parameters: - in: query name: page description: 'The page number for paginated feed results. Must be at least 1.' example: 1 required: false schema: type: integer description: 'The page number for paginated feed results. Must be at least 1.' example: 1 nullable: true - in: query name: date description: 'Filter feed items reported on or after this date, up to today. Must not be older than 90 days from today. Must be a valid date in the format Y-m-d.' example: '2026-07-29' required: false schema: type: string description: 'Filter feed items reported on or after this date, up to today. Must not be older than 90 days from today. Must be a valid date in the format Y-m-d.' example: '2026-07-29' nullable: true responses: 200: description: '' content: application/json: schema: type: object example: success: true message: 'Domain feed retrieved successfully.' data: - reported_at: 'Mar 28, 2026 5:30PM' mail_stream: 'Transactional Stream' domain: id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: example.com description: 'Primary sending domain' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' spf_domain: example.com seed_message: mail_from_name: 'Test Sender' mail_from: sender@example.com subject: 'Seed message' preview_line: 'This is a preview.' is_compliant: true is_blocklisted: false is_test: false - message: 'SPF is valid.' reported_at: 'Mar 28, 2026 4:45PM' mail_stream: 'Transactional Stream' domain: id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: example.com description: 'Primary sending domain' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' spf_domain: null seed_message: null meta: current_page: 1 from: 1 last_page: 2 per_page: 15 to: 15 total: 16 properties: success: type: boolean example: true message: type: string example: 'Domain feed retrieved successfully.' data: type: array example: - reported_at: 'Mar 28, 2026 5:30PM' mail_stream: 'Transactional Stream' domain: id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: example.com description: 'Primary sending domain' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' spf_domain: example.com seed_message: mail_from_name: 'Test Sender' mail_from: sender@example.com subject: 'Seed message' preview_line: 'This is a preview.' is_compliant: true is_blocklisted: false is_test: false - message: 'SPF is valid.' reported_at: 'Mar 28, 2026 4:45PM' mail_stream: 'Transactional Stream' domain: id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: example.com description: 'Primary sending domain' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' spf_domain: null seed_message: null items: type: object properties: reported_at: type: string example: 'Mar 28, 2026 5:30PM' mail_stream: type: string example: 'Transactional Stream' domain: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: type: string example: example.com description: type: string example: 'Primary sending domain' created_at: type: string example: '2026-03-28T10:30:00.000000Z' updated_at: type: string example: '2026-03-28T10:30:00.000000Z' spf_domain: type: string example: example.com seed_message: type: object properties: mail_from_name: type: string example: 'Test Sender' mail_from: type: string example: sender@example.com subject: type: string example: 'Seed message' preview_line: type: string example: 'This is a preview.' is_compliant: type: boolean example: true is_blocklisted: type: boolean example: false is_test: type: boolean example: false meta: type: object properties: current_page: type: integer example: 1 from: type: integer example: 1 last_page: type: integer example: 2 per_page: type: integer example: 15 to: type: integer example: 15 total: type: integer example: 16 403: description: '' content: application/json: schema: type: object example: success: false message: 'Feed is only available for activated domains.' data: [] properties: success: type: boolean example: false message: type: string example: 'Feed is only available for activated domains.' data: type: array example: [] tags: - Domains parameters: - in: path name: id description: 'The ULID of the domain.' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: true schema: type: string '/api/v1/domains/{id}': get: summary: 'Retrieve Domain.' operationId: retrieveDomain description: '' parameters: - in: query name: start_date description: 'Filter related IPs from this date (Y-m-d). Maximum selected range is 90 days.' example: '2026-01-01' required: false schema: type: string description: 'Filter related IPs from this date (Y-m-d). Maximum selected range is 90 days.' example: '2026-01-01' - in: query name: end_date description: 'Filter related IPs until this date (Y-m-d). Maximum selected range is 90 days.' example: '2026-03-31' required: false schema: type: string description: 'Filter related IPs until this date (Y-m-d). Maximum selected range is 90 days.' example: '2026-03-31' - in: query name: related_ips_page description: 'The page number for related IP results.' example: 1 required: false schema: type: integer description: 'The page number for related IP results.' example: 1 responses: 200: description: '' content: application/json: schema: type: object example: success: true message: 'Domain retrieved successfully.' data: id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: example.com description: 'Primary sending domain' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' logo: null team: name: 'Owner Custom Team' mail_streams: - name: 'Transactional Stream' type: transactional logo: 'https://cdn.example.com/mail-streams/transactional.svg' configuration: spf_domains: [] dkim_selectors: [] bimi_selectors: [] dmarc: valid: true record: 'v=DMARC1; p=none;' mx: valid: true records: - mx1.example.com - mx2.example.com created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' alignment: items: [] settings: estimated_message_volume: '1000' general_settings: estimated_message_volume: '1000' shared_team_ids: [] mail_streams: - name: 'Transactional Stream' type: transactional general_settings: [] spf_domains: [] compliance: is_compliant: true pre_send: is_compliant: true mail_streams: - name: 'Transactional Stream' type: transactional is_compliant: true checks: ips: true one_click_unsub: false blocklists: true spf: true dkim: true dmarc: true tls: true post_send: is_compliant: false requirements: spf: true dkim: null dmarc_alignment: null dmarc_policy: false encryption: null user_reported_spam_rate: null dns_records: null one_click_unsubscribe: null honor_unsubscribe: null message_formatting: null subdomain: domain_id: mail.example.com requirements: spf: false dkim: false dmarc_alignment: null dmarc_policy: null encryption: null user_reported_spam_rate: null dns_records: null one_click_unsubscribe: null honor_unsubscribe: null message_formatting: null mail_streams: - name: 'Transactional Stream' type: transactional is_compliant: true checks: ips: true one_click_unsub: false blocklists: true spf: true dkim: true dmarc: true tls: true complaint_rate_averages: periods: [] related_ips: date_range: start_date: '2026-01-01 00:00:00' end_date: '2026-03-31 23:59:59' items: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: 192.0.2.10 description: 'Primary sending IP' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' meta: current_page: 1 last_page: 1 per_page: 10 total: 0 blocklists: is_blacklist: false blacklist_count: 0 listed_count: 0 listed_muted: 0 listed_details: [] properties: success: type: boolean example: true message: type: string example: 'Domain retrieved successfully.' data: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: type: string example: example.com description: type: string example: 'Primary sending domain' created_at: type: string example: '2026-03-28T10:30:00.000000Z' updated_at: type: string example: '2026-03-28T10:30:00.000000Z' logo: type: string example: null nullable: true team: type: object properties: name: type: string example: 'Owner Custom Team' mail_streams: type: array example: - name: 'Transactional Stream' type: transactional logo: 'https://cdn.example.com/mail-streams/transactional.svg' items: type: object properties: name: type: string example: 'Transactional Stream' type: type: string example: transactional logo: type: string example: 'https://cdn.example.com/mail-streams/transactional.svg' configuration: type: object properties: spf_domains: type: array example: [] dkim_selectors: type: array example: [] bimi_selectors: type: array example: [] dmarc: type: object properties: valid: type: boolean example: true record: type: string example: 'v=DMARC1; p=none;' mx: type: object properties: valid: type: boolean example: true records: type: array example: - mx1.example.com - mx2.example.com items: type: string created_at: type: string example: '2026-03-28T10:30:00.000000Z' updated_at: type: string example: '2026-03-28T10:30:00.000000Z' alignment: type: object properties: items: type: array example: [] settings: type: object properties: estimated_message_volume: type: string example: '1000' general_settings: type: object properties: estimated_message_volume: type: string example: '1000' shared_team_ids: type: array example: [] mail_streams: type: array example: - name: 'Transactional Stream' type: transactional general_settings: [] items: type: object properties: name: type: string example: 'Transactional Stream' type: type: string example: transactional general_settings: type: array example: [] spf_domains: type: array example: [] compliance: type: object properties: is_compliant: type: boolean example: true pre_send: type: object properties: is_compliant: type: boolean example: true mail_streams: type: array example: - name: 'Transactional Stream' type: transactional is_compliant: true checks: ips: true one_click_unsub: false blocklists: true spf: true dkim: true dmarc: true tls: true items: type: object properties: name: type: string example: 'Transactional Stream' type: type: string example: transactional is_compliant: type: boolean example: true checks: type: object properties: { ips: { type: boolean, example: true }, one_click_unsub: { type: boolean, example: false }, blocklists: { type: boolean, example: true }, spf: { type: boolean, example: true }, dkim: { type: boolean, example: true }, dmarc: { type: boolean, example: true }, tls: { type: boolean, example: true } } post_send: type: object properties: is_compliant: type: boolean example: false requirements: type: object properties: spf: type: boolean example: true dkim: type: string example: null nullable: true dmarc_alignment: type: string example: null nullable: true dmarc_policy: type: boolean example: false encryption: type: string example: null nullable: true user_reported_spam_rate: type: string example: null nullable: true dns_records: type: string example: null nullable: true one_click_unsubscribe: type: string example: null nullable: true honor_unsubscribe: type: string example: null nullable: true message_formatting: type: string example: null nullable: true subdomain: type: object properties: domain_id: type: string example: mail.example.com requirements: type: object properties: spf: { type: boolean, example: false } dkim: { type: boolean, example: false } dmarc_alignment: { type: string, example: null, nullable: true } dmarc_policy: { type: string, example: null, nullable: true } encryption: { type: string, example: null, nullable: true } user_reported_spam_rate: { type: string, example: null, nullable: true } dns_records: { type: string, example: null, nullable: true } one_click_unsubscribe: { type: string, example: null, nullable: true } honor_unsubscribe: { type: string, example: null, nullable: true } message_formatting: { type: string, example: null, nullable: true } mail_streams: type: array example: - name: 'Transactional Stream' type: transactional is_compliant: true checks: ips: true one_click_unsub: false blocklists: true spf: true dkim: true dmarc: true tls: true items: type: object properties: name: type: string example: 'Transactional Stream' type: type: string example: transactional is_compliant: type: boolean example: true checks: type: object properties: ips: type: boolean example: true one_click_unsub: type: boolean example: false blocklists: type: boolean example: true spf: type: boolean example: true dkim: type: boolean example: true dmarc: type: boolean example: true tls: type: boolean example: true complaint_rate_averages: type: object properties: periods: type: array example: [] related_ips: type: object properties: date_range: type: object properties: start_date: type: string example: '2026-01-01 00:00:00' end_date: type: string example: '2026-03-31 23:59:59' items: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: 192.0.2.10 description: 'Primary sending IP' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: type: string example: 192.0.2.10 description: type: string example: 'Primary sending IP' created_at: type: string example: '2026-03-28T10:30:00.000000Z' updated_at: type: string example: '2026-03-28T10:30:00.000000Z' meta: type: object properties: current_page: type: integer example: 1 last_page: type: integer example: 1 per_page: type: integer example: 10 total: type: integer example: 0 blocklists: type: object properties: is_blacklist: type: boolean example: false blacklist_count: type: integer example: 0 listed_count: type: integer example: 0 listed_muted: type: integer example: 0 listed_details: type: array example: [] tags: - Domains requestBody: required: false content: application/json: schema: type: object properties: related_ips_page: type: integer description: 'Must be at least 1.' example: 16 nullable: true start_date: type: string description: 'Must be a valid date in the format Y-m-d. Must be a date before or equal to today. Must be a date before or equal to end_date.' example: '2022-08-23' nullable: true end_date: type: string description: 'Must be a valid date in the format Y-m-d. Must be a date before or equal to today. Must be a date after or equal to start_date.' example: '2052-08-21' nullable: true parameters: - in: path name: id description: 'The ULID of the domain.' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: true schema: type: string /api/v1/ips: get: summary: 'Retrieve IPs.' operationId: retrieveIPs description: '' parameters: - in: query name: page description: 'The page number. Must be at least 1.' example: 1 required: false schema: type: integer description: 'The page number. Must be at least 1.' example: 1 - in: query name: per_page description: 'The number of IPs per page. Must be at least 1. Must not be greater than 100.' example: 15 required: false schema: type: integer description: 'The number of IPs per page. Must be at least 1. Must not be greater than 100.' example: 15 responses: 200: description: '' content: application/json: schema: type: object example: success: true message: 'IPs retrieved successfully.' data: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: 192.0.2.10 description: 'Primary sending IP' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' meta: current_page: 1 from: 1 last_page: 1 per_page: 15 to: 1 total: 1 properties: success: type: boolean example: true message: type: string example: 'IPs retrieved successfully.' data: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: 192.0.2.10 description: 'Primary sending IP' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: type: string example: 192.0.2.10 description: type: string example: 'Primary sending IP' created_at: type: string example: '2026-03-28T10:30:00.000000Z' updated_at: type: string example: '2026-03-28T10:30:00.000000Z' meta: type: object properties: current_page: type: integer example: 1 from: type: integer example: 1 last_page: type: integer example: 1 per_page: type: integer example: 15 to: type: integer example: 1 total: type: integer example: 1 tags: - IPs '/api/v1/ips/{id}/feed': get: summary: 'Retrieve IP Feed.' operationId: retrieveIPFeed description: '' parameters: - in: query name: page description: 'The page number for paginated feed results. Must be at least 1.' example: 1 required: false schema: type: integer description: 'The page number for paginated feed results. Must be at least 1.' example: 1 nullable: true - in: query name: date description: 'Filter feed items reported on or after this date, up to today. Must not be older than 90 days from today. Must be a valid date in the format Y-m-d.' example: '2026-07-29' required: false schema: type: string description: 'Filter feed items reported on or after this date, up to today. Must not be older than 90 days from today. Must be a valid date in the format Y-m-d.' example: '2026-07-29' nullable: true responses: 200: description: '' content: application/json: schema: type: object example: success: true message: 'IP feed retrieved successfully.' data: - reported_at: 'Mar 28, 2026 5:30PM' mail_stream: 'Transactional Stream' ip: id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: 192.0.2.10 description: 'Primary sending IP' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' seed_message: mail_from_name: 'Test Sender' mail_from: sender@example.com subject: 'Seed message' preview_line: 'This is a preview.' is_compliant: true is_blocklisted: false is_test: false - message: 'IP is compliant.' reported_at: 'Mar 28, 2026 4:45PM' mail_stream: 'Transactional Stream' ip: id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: 192.0.2.10 description: 'Primary sending IP' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' seed_message: null meta: current_page: 1 from: 1 last_page: 2 per_page: 15 to: 15 total: 16 properties: success: type: boolean example: true message: type: string example: 'IP feed retrieved successfully.' data: type: array example: - reported_at: 'Mar 28, 2026 5:30PM' mail_stream: 'Transactional Stream' ip: id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: 192.0.2.10 description: 'Primary sending IP' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' seed_message: mail_from_name: 'Test Sender' mail_from: sender@example.com subject: 'Seed message' preview_line: 'This is a preview.' is_compliant: true is_blocklisted: false is_test: false - message: 'IP is compliant.' reported_at: 'Mar 28, 2026 4:45PM' mail_stream: 'Transactional Stream' ip: id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: 192.0.2.10 description: 'Primary sending IP' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' seed_message: null items: type: object properties: reported_at: type: string example: 'Mar 28, 2026 5:30PM' mail_stream: type: string example: 'Transactional Stream' ip: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: type: string example: 192.0.2.10 description: type: string example: 'Primary sending IP' created_at: type: string example: '2026-03-28T10:30:00.000000Z' updated_at: type: string example: '2026-03-28T10:30:00.000000Z' seed_message: type: object properties: mail_from_name: type: string example: 'Test Sender' mail_from: type: string example: sender@example.com subject: type: string example: 'Seed message' preview_line: type: string example: 'This is a preview.' is_compliant: type: boolean example: true is_blocklisted: type: boolean example: false is_test: type: boolean example: false meta: type: object properties: current_page: type: integer example: 1 from: type: integer example: 1 last_page: type: integer example: 2 per_page: type: integer example: 15 to: type: integer example: 15 total: type: integer example: 16 403: description: '' content: application/json: schema: type: object example: success: false message: 'Feed is only available for activated IPs.' data: [] properties: success: type: boolean example: false message: type: string example: 'Feed is only available for activated IPs.' data: type: array example: [] tags: - IPs parameters: - in: path name: id description: 'The ULID of the IP.' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: true schema: type: string '/api/v1/ips/{id}': get: summary: 'Retrieve IP.' operationId: retrieveIP description: '' parameters: - in: query name: start_date description: 'Filter related domains from this date (Y-m-d). Maximum selected range is 90 days.' example: '2026-01-01' required: false schema: type: string description: 'Filter related domains from this date (Y-m-d). Maximum selected range is 90 days.' example: '2026-01-01' - in: query name: end_date description: 'Filter related domains until this date (Y-m-d). Maximum selected range is 90 days.' example: '2026-03-31' required: false schema: type: string description: 'Filter related domains until this date (Y-m-d). Maximum selected range is 90 days.' example: '2026-03-31' - in: query name: related_domains_page description: 'The page number for related domain results.' example: 1 required: false schema: type: integer description: 'The page number for related domain results.' example: 1 responses: 200: description: '' content: application/json: schema: type: object example: success: true message: 'IP retrieved successfully.' data: id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: 192.0.2.10 description: 'Primary sending IP' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' logo: null team: name: 'Owner Custom Team' mail_streams: - name: 'Transactional Stream' type: transactional logo: 'https://cdn.example.com/mail-streams/transactional.svg' configuration: rdns: mail.example.com fcrdns: true rdns_summary: null provider: asn: asn: AS64500 name: 'Example ASN' location: '37.7749,-122.4194' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' settings: shared_team_ids: [] compliance: is_compliant: true sender_score: 98 checks: blocklists: true fcrdns: true complaint_rate_averages: periods: [] inbox_placement_averages: periods: [] related_domains: date_range: start_date: '2026-01-01 00:00:00' end_date: '2026-03-31 23:59:59' items: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: example.com description: 'Primary sending domain' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' meta: current_page: 1 last_page: 1 per_page: 10 total: 0 blocklists: is_blacklist: false blacklist_count: 0 listed_count: 0 listed_muted: 0 listed_details: [] properties: success: type: boolean example: true message: type: string example: 'IP retrieved successfully.' data: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: type: string example: 192.0.2.10 description: type: string example: 'Primary sending IP' created_at: type: string example: '2026-03-28T10:30:00.000000Z' updated_at: type: string example: '2026-03-28T10:30:00.000000Z' logo: type: string example: null nullable: true team: type: object properties: name: type: string example: 'Owner Custom Team' mail_streams: type: array example: - name: 'Transactional Stream' type: transactional logo: 'https://cdn.example.com/mail-streams/transactional.svg' items: type: object properties: name: type: string example: 'Transactional Stream' type: type: string example: transactional logo: type: string example: 'https://cdn.example.com/mail-streams/transactional.svg' configuration: type: object properties: rdns: type: string example: mail.example.com fcrdns: type: boolean example: true rdns_summary: type: string example: null nullable: true provider: type: object properties: asn: type: object properties: asn: type: string example: AS64500 name: type: string example: 'Example ASN' location: type: string example: '37.7749,-122.4194' created_at: type: string example: '2026-03-28T10:30:00.000000Z' updated_at: type: string example: '2026-03-28T10:30:00.000000Z' settings: type: object properties: shared_team_ids: type: array example: [] compliance: type: object properties: is_compliant: type: boolean example: true sender_score: type: integer example: 98 checks: type: object properties: blocklists: type: boolean example: true fcrdns: type: boolean example: true complaint_rate_averages: type: object properties: periods: type: array example: [] inbox_placement_averages: type: object properties: periods: type: array example: [] related_domains: type: object properties: date_range: type: object properties: start_date: type: string example: '2026-01-01 00:00:00' end_date: type: string example: '2026-03-31 23:59:59' items: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: example.com description: 'Primary sending domain' created_at: '2026-03-28T10:30:00.000000Z' updated_at: '2026-03-28T10:30:00.000000Z' items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: type: string example: example.com description: type: string example: 'Primary sending domain' created_at: type: string example: '2026-03-28T10:30:00.000000Z' updated_at: type: string example: '2026-03-28T10:30:00.000000Z' meta: type: object properties: current_page: type: integer example: 1 last_page: type: integer example: 1 per_page: type: integer example: 10 total: type: integer example: 0 blocklists: type: object properties: is_blacklist: type: boolean example: false blacklist_count: type: integer example: 0 listed_count: type: integer example: 0 listed_muted: type: integer example: 0 listed_details: type: array example: [] tags: - IPs requestBody: required: false content: application/json: schema: type: object properties: related_domains_page: type: integer description: 'Must be at least 1.' example: 16 nullable: true start_date: type: string description: 'Must be a valid date in the format Y-m-d. Must be a date before or equal to today. Must be a date before or equal to end_date.' example: '2022-08-23' nullable: true end_date: type: string description: 'Must be a valid date in the format Y-m-d. Must be a date before or equal to today. Must be a date after or equal to start_date.' example: '2052-08-21' nullable: true parameters: - in: path name: id description: 'The ULID of the IP.' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: true schema: type: string '/api/v1/intelligence/single-emails/{email}': get: summary: 'Retrieve Single Email.' operationId: retrieveSingleEmail description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 25 email: price.amber@example.org status: null created_at: '2026-07-29 17:23:44' updated_at: '2026-07-29 17:23:44' properties: data: type: object properties: id: type: integer example: 25 email: type: string example: price.amber@example.org status: type: string example: null nullable: true created_at: type: string example: '2026-07-29 17:23:44' updated_at: type: string example: '2026-07-29 17:23:44' tags: - Intelligence delete: summary: 'Delete Single Email.' operationId: deleteSingleEmail description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: message: 'Single email deleted.' deleted: true properties: message: type: string example: 'Single email deleted.' deleted: type: boolean example: true tags: - Intelligence parameters: - in: path name: email description: 'The email address to retrieve.' example: example@postmasterplus.com required: true schema: type: string /api/v1/intelligence/single-emails/scan: post: summary: 'Scan Single Email.' operationId: scanSingleEmail description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 26 email: rempel.chadrick@example.org status: null created_at: '2026-07-29 17:23:44' updated_at: '2026-07-29 17:23:44' properties: data: type: object properties: id: type: integer example: 26 email: type: string example: rempel.chadrick@example.org status: type: string example: null nullable: true created_at: type: string example: '2026-07-29 17:23:44' updated_at: type: string example: '2026-07-29 17:23:44' tags: - Intelligence requestBody: required: true content: application/json: schema: type: object properties: email: type: string description: 'The email address to scan.' example: example@postmasterplus.com actions: type: string description: 'The actions in comma separated format to perform.' example: '"verification,activity,postal_append"' required: - email - actions /api/v1/blocklist/scan/start: post: summary: 'Start Blocklist Scan.' operationId: startBlocklistScan description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 01kyqeenbz4r9whbcgqr23yafz status: pending status_label: Pending unique_hosts_checked: 3 total_hosts_detected: null urls_scanned: 0 urls_skipped: 0 blocklisted: false credits_used: 0 error_message: '' started_at: null completed_at: null success: true message: 'Blocklist check started successfully.' properties: data: type: object properties: id: type: string example: 01kyqeenbz4r9whbcgqr23yafz description: 'The unique identifier for the blocklist check.' status: type: string example: pending description: 'The status of the blocklist check. Example: `pending`, `processing`, `completed`, `partially_completed`, `failed`' enum: - pending - processing - completed - partially_completed - failed status_label: type: string example: Pending description: 'Human-friendly status label. Example: Pending, Processing, Completed, Partially Completed, Failed' unique_hosts_checked: type: integer example: 3 description: 'The number of unique hosts checked.' total_hosts_detected: type: string example: null description: 'The number of hosts detected.' urls_scanned: type: integer example: 0 description: 'The number of URLs scanned.' urls_skipped: type: integer example: 0 description: 'The number of URLs skipped.' blocklisted: type: boolean example: false description: 'Whether the check is blocklisted.' credits_used: type: integer example: 0 description: 'The number of credits used.' error_message: type: string example: '' description: 'The error message if the check failed.' started_at: type: string example: null description: 'The date and time the check started.' completed_at: type: string example: null description: 'The date and time the check completed.' required: - id - status - status_label - unique_hosts_checked - total_hosts_detected - urls_scanned - urls_skipped - blocklisted - credits_used - error_message - started_at - completed_at success: type: boolean example: true message: type: string example: 'Blocklist check started successfully.' tags: - Blocklists requestBody: required: true content: application/json: schema: type: object properties: urls: type: array description: 'Array of HTTP(S) URLs, bare domains, or public IP addresses to scan (minimum 1 target, maximum 100 targets).' example: - 'https://optipub.com/newsletter' - optipub.com - 8.8.8.8 items: type: string follow_redirects: type: boolean description: 'optional Whether to follow redirects for full HTTP(S) URL targets. Defaults to true. Bare domains and IP targets always bypass redirect processing.' example: true required: - urls '/api/v1/blocklist/scan/status/{id}': get: summary: 'Retrieve Blocklist Scan Status.' operationId: retrieveBlocklistScanStatus description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 01kyqeenchgj12r6pbfzx4bvgx status: pending status_label: Pending unique_hosts_checked: 4 total_hosts_detected: null urls_scanned: 0 urls_skipped: 0 blocklisted: false credits_used: 0 error_message: '' started_at: null completed_at: null success: true message: 'Blocklist check status retrieved successfully.' properties: data: type: object properties: id: type: string example: 01kyqeenchgj12r6pbfzx4bvgx description: 'The unique identifier for the blocklist check.' status: type: string example: pending description: 'The status of the blocklist check. Example: `pending`, `processing`, `completed`, `partially_completed`, `failed`' enum: - pending - processing - completed - partially_completed - failed status_label: type: string example: Pending description: 'Human-friendly status label. Example: Pending, Processing, Completed, Partially Completed, Failed' unique_hosts_checked: type: integer example: 4 description: 'The number of unique hosts checked.' total_hosts_detected: type: string example: null description: 'The number of hosts detected.' urls_scanned: type: integer example: 0 description: 'The number of URLs scanned.' urls_skipped: type: integer example: 0 description: 'The number of URLs skipped.' blocklisted: type: boolean example: false description: 'Whether the check is blocklisted.' credits_used: type: integer example: 0 description: 'The number of credits used.' error_message: type: string example: '' description: 'The error message if the check failed.' started_at: type: string example: null description: 'The date and time the check started.' completed_at: type: string example: null description: 'The date and time the check completed.' required: - id - status - status_label - unique_hosts_checked - total_hosts_detected - urls_scanned - urls_skipped - blocklisted - credits_used - error_message - started_at - completed_at success: type: boolean example: true message: type: string example: 'Blocklist check status retrieved successfully.' tags: - Blocklists parameters: - in: path name: id description: 'The ULID of the blocklist check.' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: true schema: type: string /api/v1/seedboxes: get: summary: '' operationId: getApiV1Seedboxes description: '' parameters: [] responses: {} tags: - Seedbox requestBody: required: false content: application/json: schema: type: object properties: status: type: string description: '' example: revoked enum: - active - revoked nullable: true mode: type: string description: '' example: null client_reference: type: string description: 'Must not be greater than 255 characters.' example: b nullable: true per_page: type: integer description: 'Must be at least 1. Must not be greater than 100.' example: 22 page: type: integer description: 'Must be at least 1.' example: 67 post: summary: '' operationId: postApiV1Seedboxes description: '' parameters: [] responses: {} tags: - Seedbox requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Must not be greater than 120 characters.' example: b client_reference: type: string description: 'Must not be greater than 255 characters.' example: 'n' nullable: true scan_blocklists: type: boolean description: '' example: false mode: type: string description: '' example: null max_messages: type: string description: '' example: null expires_at: type: string description: '' example: null required: - name '/api/v1/seedboxes/{seedbox}/messages': get: summary: '' operationId: getApiV1SeedboxesSeedboxMessages description: '' parameters: [] responses: {} tags: - Seedbox requestBody: required: false content: application/json: schema: type: object properties: per_page: type: integer description: 'Must be at least 1. Must not be greater than 100.' example: 1 page: type: integer description: 'Must be at least 1.' example: 22 include_content: type: string description: '' example: '0' enum: - 'true' - 'false' - '1' - '0' parameters: - in: path name: seedbox description: 'The seedbox.' example: 58C6f7nnFCJ9M6rjyc6rTKMzn6 required: true schema: type: string '/api/v1/seedboxes/{seedbox}/messages/{message}': get: summary: '' operationId: getApiV1SeedboxesSeedboxMessagesMessage description: '' parameters: [] responses: {} tags: - Seedbox requestBody: required: false content: application/json: schema: type: object properties: include_content: type: string description: '' example: 'false' enum: - 'true' - 'false' - '1' - '0' parameters: - in: path name: seedbox description: 'The seedbox.' example: 58C6f7nnFCJ9M6rjyc6rTKMzn6 required: true schema: type: string - in: path name: message description: 'The message.' example: BcECdBDA-CdED-bFEA-CbCE-BcCdeBfbbebc required: true schema: type: string '/api/v1/seedboxes/{seedbox}/messages/{message}/unsubscribe': post: summary: 'Request a one-click unsubscribe for the list behind a seedbox message.' operationId: requestAOneClickUnsubscribeForTheListBehindASeedboxMessage description: "Mirrors the web endpoint exactly: this action owns no unsubscribe logic\nof its own, it resolves the message through the current team, delegates\nto the shared action, and maps the returned outcome to a status through\n{@see RequestUnsubscribeOutcome}, so every surface agrees on whether an\noutcome counts as a success. A `rate_limited` outcome answers 429 and the same\nrequest may succeed once the budget refills." parameters: [] responses: {} tags: - Seedbox parameters: - in: path name: seedbox description: 'The seedbox.' example: 58C6f7nnFCJ9M6rjyc6rTKMzn6 required: true schema: type: string - in: path name: message description: 'The message.' example: BcECdBDA-CdED-bFEA-CbCE-BcCdeBfbbebc required: true schema: type: string '/api/v1/seedboxes/{seedbox_id}/subscriptions': get: summary: '' operationId: getApiV1SeedboxesSeedbox_idSubscriptions description: '' parameters: [] responses: {} tags: - Seedbox requestBody: required: false content: application/json: schema: type: object properties: state: type: string description: '' example: unsubscribe_failed enum: - subscribed - unsubscribe_pending - unsubscribe_failed - unsubscribed - mail_after_unsubscribe_within_threshold - mail_after_unsubscribe nullable: true search: type: string description: 'Must not be greater than 255 characters.' example: b nullable: true sort: type: string description: '' example: severity enum: - severity - last_seen_at - oldest_seen_at nullable: true per_page: type: integer description: 'Must be at least 1. Must not be greater than 100.' example: 22 page: type: integer description: 'Must be at least 1.' example: 67 parameters: - in: path name: seedbox_id description: 'The ID of the seedbox.' example: architecto required: true schema: type: string '/api/v1/seedboxes/{seedbox}/subscriptions/unsubscribe-all': post: summary: 'Request an unsubscribe from every actionable list matching the given filters.' operationId: requestAnUnsubscribeFromEveryActionableListMatchingTheGivenFilters description: "Requests are paced, so this answers 202 with counts rather than a per-list\noutcome." parameters: [] responses: {} tags: - Seedbox requestBody: required: false content: application/json: schema: type: object properties: state: type: string description: '' example: mail_after_unsubscribe enum: - subscribed - unsubscribe_pending - unsubscribe_failed - unsubscribed - mail_after_unsubscribe_within_threshold - mail_after_unsubscribe nullable: true search: type: string description: 'Must not be greater than 255 characters.' example: b nullable: true sort: type: string description: '' example: last_seen_at enum: - severity - last_seen_at - oldest_seen_at nullable: true parameters: - in: path name: seedbox description: 'The seedbox.' example: 58C6f7nnFCJ9M6rjyc6rTKMzn6 required: true schema: type: string '/api/v1/seedboxes/{seedbox}/subscriptions/{subscription}/unsubscribe': post: summary: '' operationId: postApiV1SeedboxesSeedboxSubscriptionsSubscriptionUnsubscribe description: '' parameters: [] responses: {} tags: - Seedbox parameters: - in: path name: seedbox description: 'The seedbox.' example: 58C6f7nnFCJ9M6rjyc6rTKMzn6 required: true schema: type: string - in: path name: subscription description: 'The subscription.' example: '564' required: true schema: type: string '/api/v1/seedboxes/{seedbox}': get: summary: '' operationId: getApiV1SeedboxesSeedbox description: '' parameters: [] responses: {} tags: - Seedbox patch: summary: 'Update editable seedbox metadata without changing its address or lifecycle.' operationId: updateEditableSeedboxMetadataWithoutChangingItsAddressOrLifecycle description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 01kyqeeng4kbj7he3kkm3znrzv team_id: 344 name: null client_reference: null status: active address: ac141390ef87d2ce718fa457d3ef2322@b-01kyqeeng4kbj7he3kkm3znrzw.seeds.dev.optipub.com scan_blocklists: false receive_credits_per_message: 1 messages_count: 0 rejected_insufficient_credit_count: 0 unresolved_insufficient_credit_rejection_count: 0 accepting_messages: true can_delete: false revoked_at: null last_received_at: null last_rejected_insufficient_credit_at: null created_at: '2026-07-29T17:23:44+00:00' success: true message: 'Seedbox updated successfully.' properties: data: type: object properties: id: type: string example: 01kyqeeng4kbj7he3kkm3znrzv team_id: type: integer example: 344 name: type: string example: null nullable: true client_reference: type: string example: null nullable: true status: type: string example: active address: type: string example: ac141390ef87d2ce718fa457d3ef2322@b-01kyqeeng4kbj7he3kkm3znrzw.seeds.dev.optipub.com scan_blocklists: type: boolean example: false receive_credits_per_message: type: integer example: 1 messages_count: type: integer example: 0 rejected_insufficient_credit_count: type: integer example: 0 unresolved_insufficient_credit_rejection_count: type: integer example: 0 accepting_messages: type: boolean example: true can_delete: type: boolean example: false revoked_at: type: string example: null nullable: true last_received_at: type: string example: null nullable: true last_rejected_insufficient_credit_at: type: string example: null nullable: true created_at: type: string example: '2026-07-29T17:23:44+00:00' success: type: boolean example: true message: type: string example: 'Seedbox updated successfully.' tags: - Seedbox requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'A non-empty human-readable name. Omit this field to preserve the current name. Must not be greater than 120 characters.' example: 'Transactional seedbox' client_reference: type: string description: 'A stable external identifier. Send null to clear it, or omit this field to preserve it. Must not be greater than 255 characters.' example: campaign-2026-07 nullable: true scan_blocklists: type: boolean description: 'Whether future received messages should be scanned against blocklists. Enabling it requires blocklist-check:scan:start and may increase future credit usage.' example: true delete: summary: '' operationId: deleteApiV1SeedboxesSeedbox description: '' parameters: [] responses: {} tags: - Seedbox parameters: - in: path name: seedbox description: 'The seedbox.' example: 58C6f7nnFCJ9M6rjyc6rTKMzn6 required: true schema: type: string '/api/v1/seedboxes/{seedbox}/delete': delete: summary: '' operationId: deleteApiV1SeedboxesSeedboxDelete description: '' parameters: [] responses: {} tags: - Seedbox parameters: - in: path name: seedbox description: 'The seedbox.' example: 58 required: true schema: type: integer /api/v1/spam-identifiers: get: summary: 'Retrieve Spam Identifiers.' operationId: retrieveSpamIdentifiers description: "List all Gmail Postmaster Tools v2 spam (feedback loop) identifiers reported\nfor accessible domains in the given date range, along with each identifier's\naverage complaint rate across that window." parameters: - in: query name: domain_id description: 'Optionally filter identifiers to a single accessible domain ULID.' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: false schema: type: string description: 'Optionally filter identifiers to a single accessible domain ULID.' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV - in: query name: page description: 'The page number for paginated identifier results.' example: 1 required: false schema: type: integer description: 'The page number for paginated identifier results.' example: 1 - in: query name: start_date description: 'Filter identifiers from this date (Y-m-d). Maximum selected range is 90 days.' example: '2026-01-22' required: false schema: type: string description: 'Filter identifiers from this date (Y-m-d). Maximum selected range is 90 days.' example: '2026-01-22' - in: query name: end_date description: 'Filter identifiers until this date (Y-m-d). Maximum selected range is 90 days.' example: '2026-04-22' required: false schema: type: string description: 'Filter identifiers until this date (Y-m-d). Maximum selected range is 90 days.' example: '2026-04-22' responses: 200: description: '' content: application/json: schema: type: object example: success: true message: 'Spam identifiers retrieved successfully.' data: - domain: id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: example.com identifier: '66189376' sample_count: 57 average_complaint_rate: 0.12 min_complaint_rate: 0.05 max_complaint_rate: 0.31 - domain: id: 01ARZ3NDEKTSV4RRFFQ69G5FBG value: example.net identifier: '66189799' sample_count: 40 average_complaint_rate: 0.05 min_complaint_rate: 0.01 max_complaint_rate: 0.14 meta: current_page: 1 last_page: 1 per_page: 25 total: 2 properties: success: type: boolean example: true message: type: string example: 'Spam identifiers retrieved successfully.' data: type: array example: - domain: id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: example.com identifier: '66189376' sample_count: 57 average_complaint_rate: 0.12 min_complaint_rate: 0.05 max_complaint_rate: 0.31 - domain: id: 01ARZ3NDEKTSV4RRFFQ69G5FBG value: example.net identifier: '66189799' sample_count: 40 average_complaint_rate: 0.05 min_complaint_rate: 0.01 max_complaint_rate: 0.14 items: type: object properties: domain: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: type: string example: example.com identifier: type: string example: '66189376' sample_count: type: integer example: 57 average_complaint_rate: type: number example: 0.12 min_complaint_rate: type: number example: 0.05 max_complaint_rate: type: number example: 0.31 meta: type: object properties: current_page: type: integer example: 1 last_page: type: integer example: 1 per_page: type: integer example: 25 total: type: integer example: 2 tags: - 'Spam Identifiers' '/api/v1/spam-identifiers/{identifier}': get: summary: 'Retrieve Spam Identifier.' operationId: retrieveSpamIdentifier description: "Return the daily Gmail complaint rate time series for a single spam\n(feedback loop) identifier across accessible domains, plus the aggregate\naverage over the selected date range for each domain." parameters: - in: query name: domain_id description: 'Optionally filter the identifier to a single accessible domain ULID.' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: false schema: type: string description: 'Optionally filter the identifier to a single accessible domain ULID.' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV - in: query name: start_date description: 'Start date of the reporting window (Y-m-d). Maximum selected range is 90 days.' example: '2026-01-22' required: false schema: type: string description: 'Start date of the reporting window (Y-m-d). Maximum selected range is 90 days.' example: '2026-01-22' - in: query name: end_date description: 'End date of the reporting window (Y-m-d). Maximum selected range is 90 days.' example: '2026-04-22' required: false schema: type: string description: 'End date of the reporting window (Y-m-d). Maximum selected range is 90 days.' example: '2026-04-22' responses: 200: description: '' content: application/json: schema: type: object example: success: true message: 'Spam identifier retrieved successfully.' data: - identifier: '66189376' domain: id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: example.com date_range: start_date: '2026-01-22' end_date: '2026-04-22' aggregate: average_complaint_rate: 0.12 sample_count: 57 time_series: - date: '2026-01-22' complaint_rate: 0.1 - date: '2026-01-23' complaint_rate: null properties: success: type: boolean example: true message: type: string example: 'Spam identifier retrieved successfully.' data: type: array example: - identifier: '66189376' domain: id: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: example.com date_range: start_date: '2026-01-22' end_date: '2026-04-22' aggregate: average_complaint_rate: 0.12 sample_count: 57 time_series: - date: '2026-01-22' complaint_rate: 0.1 - date: '2026-01-23' complaint_rate: null items: type: object properties: identifier: type: string example: '66189376' domain: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV value: type: string example: example.com date_range: type: object properties: start_date: type: string example: '2026-01-22' end_date: type: string example: '2026-04-22' aggregate: type: object properties: average_complaint_rate: type: number example: 0.12 sample_count: type: integer example: 57 time_series: type: array example: - date: '2026-01-22' complaint_rate: 0.1 - date: '2026-01-23' complaint_rate: null items: type: object properties: date: type: string example: '2026-01-22' complaint_rate: type: number example: 0.1 404: description: '' content: application/json: schema: type: object example: success: false message: 'Spam identifier not found for accessible domains in the selected date range.' data: [] properties: success: type: boolean example: false message: type: string example: 'Spam identifier not found for accessible domains in the selected date range.' data: type: array example: [] tags: - 'Spam Identifiers' parameters: - in: path name: identifier description: 'The Gmail Postmaster Tools v2 spam (feedback loop) identifier.' example: '66189376' required: true schema: type: string /api/v1/screenshot/take: post: summary: 'Take Screenshot.' operationId: takeScreenshot description: 'Take a screenshot of a URL or HTML content.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 01kyqeend9c0qwfwztj191xwy7 url: 'https://assets.optipub.com/postmaster/screenshots/01kyqeend124bnda48w7672n1b/01kyqeend9c0qwfwztj191xwy7.png' format: png width: 1024 height: 600 device_scale: 3 credits_used: 1 started_at: '2026-07-04T11:25:09+00:00' completed_at: '2026-07-04T11:25:22+00:00' created_at: '2026-07-29T17:23:44+00:00' success: true message: 'Screenshot taken successfully.' properties: data: type: object properties: id: type: string example: 01kyqeend9c0qwfwztj191xwy7 description: 'The unique identifier for the screenshot.' url: type: string example: 'https://assets.optipub.com/postmaster/screenshots/01kyqeend124bnda48w7672n1b/01kyqeend9c0qwfwztj191xwy7.png' description: 'The URL of the screenshot image.' format: type: string example: png description: 'The format of the screenshot image. Example: `png`, `jpeg`' width: type: integer example: 1024 description: 'The width of the screenshot in pixels.' height: type: integer example: 600 description: 'The height of the screenshot in pixels.' device_scale: type: integer example: 3 description: 'The device scale factor used (1-3). Higher values produce sharper images.' credits_used: type: integer example: 1 description: 'The number of credits used for this screenshot.' started_at: type: string example: '2026-07-04T11:25:09+00:00' description: 'The date and time when the screenshot capture started.' completed_at: type: string example: '2026-07-04T11:25:22+00:00' description: 'The date and time when the screenshot capture completed.' created_at: type: string example: '2026-07-29T17:23:44+00:00' description: 'The date and time the screenshot was created.' required: - id - url - format - width - height - device_scale - credits_used - started_at - completed_at - created_at success: type: boolean example: true message: type: string example: 'Screenshot taken successfully.' tags: - Tools requestBody: required: false content: application/json: schema: type: object properties: url: type: string description: 'URL to screenshot (required if html is not provided).' example: '"https://example.com"' nullable: true html: type: string description: 'HTML content to screenshot (required if url is not provided).' example: null nullable: true width: type: integer description: 'optional Viewport width in pixels (320-1920). Defaults to 1280.' example: 1280 nullable: true height: type: integer description: 'optional Viewport height in pixels (240-1080). Defaults to 720.' example: 720 nullable: true format: type: string description: 'optional Image format (png, jpeg, or webp). Defaults to png.' example: '"png"' nullable: true device_scale: type: integer description: 'optional Device scale factor for higher resolution (1-3). Defaults to 1 for retina-quality images.' example: 1 nullable: true /api/v1/screenshots: get: summary: 'List Screenshots.' operationId: listScreenshots description: 'Retrieve a paginated list of screenshots for the current team.' parameters: - in: query name: per_page description: 'The number of screenshots per page (1-100). Defaults to 15. Must be at least 1. Must not be greater than 100.' example: 15 required: false schema: type: integer description: 'The number of screenshots per page (1-100). Defaults to 15. Must be at least 1. Must not be greater than 100.' example: 15 - in: query name: page description: 'The page number. Must be at least 1.' example: 1 required: false schema: type: integer description: 'The page number. Must be at least 1.' example: 1 - in: query name: sort description: 'Sort order. Use `-` prefix for descending. Options: `created_at`, `-created_at`, `format`, `-format`. Defaults to `-created_at`.' example: '-created_at' required: false schema: type: string description: 'Sort order. Use `-` prefix for descending. Options: `created_at`, `-created_at`, `format`, `-format`. Defaults to `-created_at`.' example: '-created_at' enum: - created_at - '-created_at' - format - '-format' responses: 200: description: '' content: application/json: schema: type: object example: success: true message: 'Screenshots retrieved successfully.' data: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAV url: 'https://assets.optipub.com/postmaster/screenshots/01arz3ndektsv4rrffq69g5fav/01arz3ndektsv4rrffq69g5fav.png' format: png width: 1280 height: 720 credits_used: 1 created_at: '2024-01-15T10:30:00Z' meta: current_page: 1 from: 1 last_page: 5 per_page: 15 to: 15 total: 75 properties: success: type: boolean example: true message: type: string example: 'Screenshots retrieved successfully.' data: type: array example: - id: 01ARZ3NDEKTSV4RRFFQ69G5FAV url: 'https://assets.optipub.com/postmaster/screenshots/01arz3ndektsv4rrffq69g5fav/01arz3ndektsv4rrffq69g5fav.png' format: png width: 1280 height: 720 credits_used: 1 created_at: '2024-01-15T10:30:00Z' items: type: object properties: id: type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV url: type: string example: 'https://assets.optipub.com/postmaster/screenshots/01arz3ndektsv4rrffq69g5fav/01arz3ndektsv4rrffq69g5fav.png' format: type: string example: png width: type: integer example: 1280 height: type: integer example: 720 credits_used: type: integer example: 1 created_at: type: string example: '2024-01-15T10:30:00Z' meta: type: object properties: current_page: type: integer example: 1 from: type: integer example: 1 last_page: type: integer example: 5 per_page: type: integer example: 15 to: type: integer example: 15 total: type: integer example: 75 tags: - Tools '/api/v1/screenshot/{id}': get: summary: 'Get Screenshot.' operationId: getScreenshot description: 'Retrieve details of a specific screenshot by its ID.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 01kyqeene5jwevscsb4cz6cmkt url: 'https://assets.optipub.com/postmaster/screenshots/01kyqeendx8v0dbk12y5ks5pq9/01kyqeene5jwevscsb4cz6cmkt.png' format: png width: 800 height: 600 device_scale: 2 credits_used: 1 started_at: '2026-07-20T08:05:42+00:00' completed_at: '2026-07-20T08:06:12+00:00' created_at: '2026-07-29T17:23:44+00:00' success: true message: 'Screenshot retrieved successfully.' properties: data: type: object properties: id: type: string example: 01kyqeene5jwevscsb4cz6cmkt description: 'The unique identifier for the screenshot.' url: type: string example: 'https://assets.optipub.com/postmaster/screenshots/01kyqeendx8v0dbk12y5ks5pq9/01kyqeene5jwevscsb4cz6cmkt.png' description: 'The URL of the screenshot image.' format: type: string example: png description: 'The format of the screenshot image. Example: `png`, `jpeg`' width: type: integer example: 800 description: 'The width of the screenshot in pixels.' height: type: integer example: 600 description: 'The height of the screenshot in pixels.' device_scale: type: integer example: 2 description: 'The device scale factor used (1-3). Higher values produce sharper images.' credits_used: type: integer example: 1 description: 'The number of credits used for this screenshot.' started_at: type: string example: '2026-07-20T08:05:42+00:00' description: 'The date and time when the screenshot capture started.' completed_at: type: string example: '2026-07-20T08:06:12+00:00' description: 'The date and time when the screenshot capture completed.' created_at: type: string example: '2026-07-29T17:23:44+00:00' description: 'The date and time the screenshot was created.' required: - id - url - format - width - height - device_scale - credits_used - started_at - completed_at - created_at success: type: boolean example: true message: type: string example: 'Screenshot retrieved successfully.' tags: - Tools parameters: - in: path name: id description: 'The ULID of the screenshot.' example: 01ARZ3NDEKTSV4RRFFQ69G5FAV required: true schema: type: string