AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured approach to using the AWS End User Messaging SMS and Voice (pinpoint-sms-voice-v2) API. It guides users through the rapid setup of RCS Business Messaging test agents and Notify OTP configurations, as well as the more complex lifecycle of production registration for various messaging identities. It emphasizes using the AWS MCP server for secure, audited execution and provides clear paths for both testing and moving to production-grade messaging.
What it does
- Creates branded RCS test agents with rich cards and suggested replies.
- Configures Notify for OTP delivery using AWS-managed templates.
- Discovers registration requirements for specific countries and identity types.
- Executes the full registration lifecycle including submission and denial recovery.
- Provides procedures for exiting the SMS sandbox and upgrading to production tiers.
- Offers guidance on least-privilege IAM policies and security best practices.
When to use it
- When you need to send rich, branded RCS messages to test devices.
- When you require a fast, production-ready OTP verification solution.
- When you need to determine registration requirements for international messaging.
- When you are ready to move messaging identities from sandbox to production.
- When you need to manage the registration lifecycle for 10DLC, toll-free, or short codes.
Advantages
- Enables rapid prototyping with no phone number purchase required.
- Provides a unified engine for diverse registration types.
- Includes built-in failure mode analysis and cleanup procedures.
- Promotes secure practices through least-privilege IAM and audit logging.
- Supports both CLI and MCP-based execution for flexibility.
Usage examples
- “Help me set up an RCS test agent to send a branded message.”
- The agent will guide you through creating an RCS agent, adding a verified test device, and sending your first rich message using the pinpoint-sms-voice-v2 API.
- “How do I send an OTP code using AWS Notify?”
- The agent will assist in creating a Notify configuration, selecting an approved template, and sending a verification code to your specified phone number.
- “What are the registration requirements for sending SMS in France?”
- The agent will query live API definitions to identify the specific registration type and field requirements for the target country.
- “I need to move my SMS identity out of the sandbox.”
- The agent will walk you through the production go-to-production guide, including checking account attributes and managing spend limits.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/aws/aws-sms-voice/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip aws-sms-voice.zip -d .agents/skills
Documentation by AWS
AWS End User Messaging — SMS, Voice, RCS & Notify
Overview
AWS End User Messaging SMS and Voice (the pinpoint-sms-voice-v2 API) is the
control and data plane for SMS, Voice, RCS Business Messaging, and Notify (OTP).
This skill covers the two fastest onboarding paths — each reaches
a real message on a real phone in about five minutes, with no phone-number
purchase and no carrier registration:
Create an RCS test agent and send your first branded message — a branded RCS Business Messaging agent, a verified test device, and a rich outbound + inbound message. See references/hello-rcs-test-agent.md.
Send an OTP with Notify — a one-time-passcode text through AWS-managed sending identities and pre-approved templates. See references/hello-notify-otp.md.
Beyond onboarding, this skill takes an identity to production registration in three steps:
Find which registration a country requires — discover the registration type and its live field set for a target country and identity type, reconciled with the official docs. See references/registration-requirements-by-country.md.
Run the registration lifecycle — the universal engine (create, derive fields, fill, submit, poll, recover from denial, resubmit) shared by every registration type, including RCS country launch. See references/registration-core-engine.md.
Take an identity to production — exit the SMS sandbox, launch RCS in a country with carrier monitoring and SMS fallback, upgrade Notify to Advanced, and apply production hygiene (keywords, configuration sets, protect configurations). See references/customer-go-to-production-guide.md.
Guardrail — where this skill's files live (MCP vs local install)
This skill can be loaded two ways, and the references/ files resolve differently:
Loaded through the AWS MCP
retrieve_skilltool. Reference files do not exist on the local filesystem. Fetch them viaretrieve_skillwith thefileparameter (e.g.,file="references/hello-rcs-test-agent.md"). Do NOTfile_readthese paths locally — they are not there.Installed locally (e.g.,
.kiro/skills/aws-sms-voice/). Read references from the local skill directory using the relative paths shown in this file.
This applies only to the skill's own packaged files. User-created artifacts (brand-assets/, temp files) are always in the user's working directory.
Execute commands using available tools from the AWS MCP server when connected — it provides sandboxed execution, audit logging, and observability. When the MCP server is not available, fall back to the AWS CLI or shell as needed.
Choosing a path
| You want to… | Go to |
|---|---|
| Send rich, branded messages (cards, logo, two-way) to your own test phone | hello-rcs-test-agent.md |
| Send a verification code / OTP to any supported phone, fastest possible path | hello-notify-otp.md |
| Find out which registration a country needs and what fields it requires | registration-requirements-by-country.md |
| Create and submit a registration of any type (10DLC, toll-free, sender ID, RCS launch, Notify tier) | registration-core-engine.md |
| Take an identity to production (sandbox exit, RCS carrier launch + fallback, Notify Advanced, hygiene) | customer-go-to-production-guide.md |
RCS test agents deliver only to verified test devices and require a short brand registration (auto-reviewed in minutes). Notify sends to any recipient in its supported countries immediately, but is limited to AWS-managed OTP templates. Pick RCS to explore rich messaging; pick Notify for the shortest path to a production-grade verification text.
Before you start (both paths)
The AWS MCP server is recommended for the best experience here — it runs the many
pinpoint-sms-voice-v2 and sts calls with sandboxed execution, audit logging, and
observability. It is not a hard requirement: every step also works with the plain AWS CLI or the
AWS Agent Toolkit when the MCP server is not available.
Credentials. Run
aws sts get-caller-identity --region <REGION>(pass--regionto use the regional STS endpoint; the globalsts.amazonaws.comendpoint is legacy). If it fails, configure the user's auth (named profile / SSO / access keys —--profile <PROFILE>on every command if a profile is in play) and prefer an assumed IAM role with ephemeral credentials. Each reference file's Prerequisites carry the full auth, CloudTrail-audit, and CLI-freshness steps.Least-privilege access. These tasks need a small set of specific
sms-voice:actions in the target account (the reference files enumerate the read/write actions each step uses — for examplesms-voice:DescribeRcsAgents,CreateRcsAgent,CreateRegistration,CreateNotifyConfiguration, andSendNotifyTextMessage). Scope the policy to exactly the actions the chosen path uses; do not grantsms-voice:*or*FullAccess.Don't trust the CLI version. Treat any
Invalid choice '<operation>'on apinpoint-sms-voice-v2command, at any step, as a stale/partial local service model (not a permissions or account problem). The RCS and Notify reference files (prerequisite 3) carry the full reactive resolution: clear a stale~/.aws/models/pinpoint-sms-voice-v2/override, else upgrade the AWS CLI, with a boto3 fallback.AccessDeniedExceptionmeans the identity is missing the requiredsms-voice:permissions.
Each reference file is self-contained: it tracks the IDs you collect as session state, audits required inputs against the service before any submit, and ends with a Failure modes table and a Cleanup section. Follow the file for the path the user chose rather than improvising the API sequence — several steps fail silently or depend on service-version-specific field sets that must be read live.
Security Considerations
Least-privilege IAM. Scope policies to specific
sms-voice:actions; never use*FullAccessorsms-voice:*in production. The reference files enumerate the minimal read/write actions each onboarding path needs.Ephemeral credentials. Assume an IAM role with ephemeral credentials; never embed long-lived access keys in code, config, or environment variables.
No secrets in messages or fields. OTP codes and message bodies can surface in CloudTrail and downstream logs — treat them as sensitive and never hardcode real codes. Enable CloudTrail logging for
sms-voiceAPI calls and encrypt CloudTrail logs and CloudWatch Log groups with a KMS CMK. Attach a configuration set with an event destination (CloudWatch Logs or Kinesis) for delivery monitoring before production traffic. Create CloudWatch alarms on key security signals (repeatedAccessDeniedException, unusual send volumes, spend limit approaching threshold) for proactive alerting. Registration contact fields (email, phone, URLs) are submitted to partner review; use real but non-sensitive business contacts.Consent and opt-out. Only message recipients who have opted in. Honor STOP / opt-out state; the RCS path shows how to check the opt-out list before sending. Test agents intentionally restrict delivery to verified test devices — do not work around that to reach unconsented numbers.
Spend limits and abuse. Default account spend limits are intentionally low; raise them deliberately and monitor. Notify enforces a non-adjustable per-day cap per destination — do not attempt to bypass it.
Destructive cleanup. The teardown steps delete agents, registrations, and configurations. They are irreversible — confirm with the user before running cleanup, and note RCS agents have deletion protection enabled by default in the onboarding flow.
Additional Resources
Files
- ATTRIBUTION.mdAdded by AutoGineer929 B
- LICENSELicence file added by AutoGineer9.9 KiB
- NOTICELicence file added by AutoGineer67 B
- SKILL.md9.7 KiB
- references/customer-go-to-production-guide.md17.4 KiB
- references/hello-notify-otp.md12.1 KiB
- references/hello-rcs-test-agent.md38.5 KiB
- references/registration-core-engine.md17.1 KiB
- references/registration-requirements-by-country.md11.5 KiB
references/registration-core-engine.md
AWS End User Messaging: The core registration engine
Every registered origination identity — 10DLC brand/campaign, toll-free, short code, sender ID, RCS country launch, and Notify tier upgrade — runs through the SAME registration engine. This file is that engine: create a registration, derive its field set live, fill every field, submit, poll two independent state machines, and recover from a denial by re-filling ALL fields. WHICH type a given country and identity needs, and what that type requires, is a live-discovery question and is deliberately not here: references/registration-requirements-by-country.md. Production reviews range from about a day to several months by type and country — the job is to submit correctly, set expectations, and leave the user a monitoring loop.
You run every command yourself. The user provides inputs and confirms results. Stop and consult the Failure modes table on any error.
Session state
| Value | Format | Source |
|---|---|---|
REGION | e.g. us-east-1 | ask the user (default us-east-1) |
REG_TYPE | e.g. <ISO2>_RCS_LAUNCH_REGISTRATION | discovery per registration-requirements-by-country |
REG_ID | registration-... | CreateRegistration response |
RESOURCE_ID | rcs-... / phone-... | the resource the registration gates, if any |
ATTACHMENT_ID | attachment-... | CreateRegistrationAttachment response, if the schema has ATTACHMENT fields |
Prerequisites
AWS account with the AWS End User Messaging SMS and Voice service enabled.
IAM role with least-privilege
sms-voice:permissions for the registration actions used below (CreateRegistration,CreateRegistrationAssociation,DescribeRegistrationFieldDefinitions,PutRegistrationFieldValue,SubmitRegistrationVersion,DescribeRegistrations,CreateRegistrationVersion, andRequestPhoneNumberwhere a number is acquired). Scope the policy to these actions; do not grantsms-voice:*or*FullAccess. Prefer assuming an IAM role with ephemeral credentials over long-lived access keys.Validate all input parameters (region, ISO country code, field values, attachment paths) before calling APIs.
These operations are available through the AWS MCP Server, which provides sandboxed execution, audit logging, and observability. When the MCP server is not available, use the AWS CLI commands shown below.
Confirm the AWS CLI is available (
aws --version). On CLI v1, URL-valued TEXT fields fail via a legacy paramfile behavior — use the--cli-input-jsonform shown in step 5, which works on both versions.
The engine — one lifecycle for every registration type
1. Pick the type
Which registration type the target country and identity type need is discovered live, never
memorized — commands and doc pointers in
references/registration-requirements-by-country.md.
Save REG_TYPE and the type's AssociationBehavior.
2. Create, and associate if the resource already exists
aws pinpoint-sms-voice-v2 create-registration \
--registration-type <REG_TYPE> --region <REGION>
aws pinpoint-sms-voice-v2 create-registration-association \
--registration-id <REG_ID> --resource-id <RESOURCE_ID> --region <REGION>Save RegistrationId as REG_ID. The second call applies only when the type gates an existing
resource (for example, an RCS agent). AssociationBehavior on the type definition says when the
association must happen:
ASSOCIATE_BEFORE_SUBMIT— you MUST link the resource before submitting, or the submission is invalid (RCS agents, including RCS country launches).ASSOCIATE_ON_APPROVAL— the resource is auto-provisioned on approval (sender IDs — no separate request step).ASSOCIATE_AFTER_COMPLETE— buy or associate the resource only after COMPLETE (phone numbers).
3. Derive the field set — the schema is always live
aws pinpoint-sms-voice-v2 describe-registration-field-definitions \
--registration-type <REG_TYPE> --region <REGION>Save per field: FieldPath, FieldType, FieldRequirement, and validation constraints. Field
sets vary by type and drift over time — derive, do not memorize. Do not filter this output;
conditional field requirements depend on the complete definition shape.
4. Upload attachments first
Only if the schema has ATTACHMENT fields: one create-registration-attachment per file
(--attachment-body and --attachment-url are mutually exclusive), within the size and format
constraints the field definition reports for that attachment field. Poll to UPLOAD_COMPLETE
before any field references the attachment ID. Prefer --attachment-body with a local
fileb:// path over a public URL for documents that contain business-identifying information.
5. Fill every field — one call per field, parameter set by the field's type
Where the values come from depends on the registration type. For a TEST registration
(e.g. TEST_RCS_LAUNCH_REGISTRATION, which only reaches verified testers), default to synthetic
placeholder values — do not interview the user field-by-field or run live field discovery to
decide what to ask; go straight to synthetic defaults, then show the user the full set of
placeholder values and let them opt out ("these are synthetic; tell me if you'd rather provide
your own for any field") and confirm before submitting. For a PRODUCTION registration (10DLC
brand/campaign, toll-free, short code, sender ID, RCS country launch), do NOT use synthetic
values: these are submitted to carrier/partner review and synthetic .example.com contacts or an
invented description will be denied. Collect real but non-sensitive business contacts from the
user (as the Security Considerations require), show them the full set, and confirm before submit.
In both cases never submit invented data unconfirmed. Treat any real values the user provides as
sensitive business-identifying PII (contact details, legal names, addresses): use them only to
populate the registration and to confirm back — do not echo them into responses or logs beyond
what confirmation requires. Because tooling may log API payloads (CloudTrail data events, MCP
server or agent-framework audit logs), the put-registration-field-value values can land in those
logs too — ensure any such log destinations are encrypted with a KMS key so the PII is protected at
the infrastructure layer, not just in the agent's own output: CloudWatch Logs log groups with a KMS
CMK, and the CloudTrail trail's S3 destination bucket with SSE-KMS (a dedicated CMK if the trail
records these data events).
aws pinpoint-sms-voice-v2 put-registration-field-value --registration-id <REG_ID> \
--field-path "<FIELD_PATH>" --text-value "<value>" --region <REGION>| FieldType | Parameter |
|---|---|
| TEXT | --text-value "<value>" |
| SELECT | --select-choices "<choice>" |
| ATTACHMENT | --registration-attachment-id "<id>" |
--field-values does not exist; do not invent it. SELECT options live under
SelectValidation.Options as a list of plain strings. On AWS CLI v1, URL-valued TEXT fields
fail because a legacy paramfile feature fetches https:// values as remote files — use the
--cli-input-json form, which works on both versions:
aws pinpoint-sms-voice-v2 put-registration-field-value --region <REGION> --cli-input-json \
'{"RegistrationId":"<REG_ID>","FieldPath":"<FIELD_PATH>","TextValue":"https://www.example.com"}'Where a field takes a phone number, provide it in E.164 format (e.g., +12065550123).
6. Audit, submit, and poll BOTH state machines
Audit what is SET against what is REQUIRED before submitting:
aws pinpoint-sms-voice-v2 describe-registration-field-values \
--registration-id <REG_ID> --region <REGION> \
--query 'RegistrationFieldValues[].FieldPath' --output text | tr '\t' '\n' | sort > /tmp/set.txt
aws pinpoint-sms-voice-v2 describe-registration-field-definitions \
--registration-type <REG_TYPE> --region <REGION> \
--query "RegistrationFieldDefinitions[].FieldPath" --output text | tr '\t' '\n' | sort > /tmp/req.txt
comm -13 /tmp/set.txt /tmp/req.txtDo not hardcode a filter on the requirement value — derive the field set from the full
definition and let the live schema decide applicability (the same reason you do not filter the
definition output above). Any line printed is a defined field you have not set; confirm from the
field's own definition whether it applies to your case before submitting. Then submit and
poll BOTH state machines — they move independently, and you MUST check both: registration
status via describe-registrations AND version status via describe-registration-versions:
aws pinpoint-sms-voice-v2 submit-registration-version --registration-id <REG_ID> --region <REGION>
aws pinpoint-sms-voice-v2 describe-registrations --registration-ids <REG_ID> \
--query 'Registrations[0].RegistrationStatus' --region <REGION>
aws pinpoint-sms-voice-v2 describe-registration-versions --registration-id <REG_ID> --region <REGION>Registration status: CREATED → SUBMITTED → REVIEWING → COMPLETE, with branches
REQUIRES_UPDATES and AUTHENTICATION_REQUIRED (a human step, typically email 2FA). Version
status: DRAFT → SUBMITTED → REVIEWING → APPROVED | DENIED. The rules that never vary:
Only COMPLETE counts. While SUBMITTED or REVIEWING, the identity behaves as unregistered — messages may go out with a generic "NOTICE"/"Unverified" sender or not at all, by country. Never tell the user "submitted, so we're good."
Locked while REVIEWING. No field edits, no disassociation — wait for the verdict or discard the version.
Denied means a FULL RESET — this is the #1 cause of a second denial. On
REQUIRES_UPDATES/DENIED, read every per-fieldDeniedReason(some types include generated fix suggestions — read them), then callcreate-registration-version. The new version starts EMPTY: every field value is reset, not just the denied ones. You MUST re-runput-registration-field-valuefor EVERY field (attachments re-reference by existing ID), then re-audit set-vs-required and resubmit. Updating only the denied field on the existing version does not work.Billing continues regardless. Purchased numbers bill monthly whatever the registration status; releasing the number is the only off switch.
7. Acquire the resource (for ASSOCIATE_AFTER_COMPLETE types)
Once COMPLETE, request the number against the registration:
aws pinpoint-sms-voice-v2 request-phone-number \
--iso-country-code <ISO2> --message-type TRANSACTIONAL \
--number-capabilities SMS --number-type <TYPE> \
--registration-id <REG_ID> --region <REGION>Save PhoneNumberId; lifecycle PENDING → ACTIVE. Capabilities (SMS/MMS/VOICE) are immutable
after purchase — choose them now. Throughput (MPS) does not auto-raise on approval; increases
are a separate Support request. Which number types a country offers, prerequisite
registrations, and throughput and ETAs are live-discovery questions:
references/registration-requirements-by-country.md.
RCS country launch — the same engine, one wrinkle
A production RCS launch is one more registration type run through the engine above. The test
agent from the RCS quickstart stays; production adds a per-country launch registration to the
SAME agent (ASSOCIATE_BEFORE_SUBMIT: associate the agent before submitting). Discover the
launch type for the target country (names follow <ISO2>_RCS_LAUNCH_REGISTRATION;
TEST_RCS_LAUNCH_REGISTRATION exists for exercising the launch flow against a test device),
create it, associate
the agent, then run steps 3–6. The launch field set is larger than the test registration
(launch details, carrier-tester access instructions, messaging samples, opt-in evidence) and a
compliance video demonstrating the agent's HELP/STOP/opt-in flows is typically required — record
the real agent behavior. Carrier review runs for months; set that expectation up front.
Per-carrier launch monitoring, SMS fallback pools, and production hygiene (keywords, configuration sets, protect configurations) are covered in references/customer-go-to-production-guide.md.
Verify
Demonstrable outcome. The engine's artifacts are state transitions — capture them as
before/after describe output the user can see: RegistrationStatus reaching COMPLETE, the
identity flipping to ACTIVE. Confirm each with a describe call, not from memory. Reviews take
days to months, so most sessions end mid-transition. When yours does, say so explicitly and
leave the user the exact poll:
aws pinpoint-sms-voice-v2 describe-registrations --registration-ids <REG_ID> \
--region <REGION> --query 'Registrations[0].RegistrationStatus'The day that returns COMPLETE, the transition in that output — next to the earlier REVIEWING
the user recorded — is the demonstrable finish.
Next steps
Which registration type a country needs, and what it requires — always live: references/registration-requirements-by-country.md
RCS test agent quickstart (verified testers only): references/hello-rcs-test-agent.md
Notify OTP quickstart: references/hello-notify-otp.md
Production launch procedures — sandbox exit, RCS carrier monitoring and fallback pools, Notify tier upgrade, production hygiene: references/customer-go-to-production-guide.md
Security Considerations
Least-privilege IAM. Scope policies to the specific
sms-voice:registration actions; never use*FullAccessorsms-voice:*.Ephemeral credentials. Assume an IAM role with ephemeral credentials; never embed long-lived access keys in code, config, or environment variables.
Sensitive registration content. Registration contact fields (email, phone, URLs) and attachments are submitted to partner review; use real but non-sensitive business contacts, and prefer local
fileb://attachment bodies over public URLs. Enable CloudTrail logging forsms-voiceAPI calls and encrypt CloudTrail logs and CloudWatch Log groups with a KMS CMK.Monitoring. Registrations can sit in
REVIEWINGfor weeks or fail silently toREQUIRES_UPDATES/DENIED. Create a CloudWatch alarm or EventBridge rule on registration status changes so the user is notified proactively rather than relying solely on manual polling. Status-change notifications can carry sensitive business information (e.g. per-field denial reasons), so encrypt the notification target: use an SNS topic with KMS encryption (alias/aws/snsor a customer-managed key), add a resource policy withaws:SourceAccountandaws:SourceArncondition keys to prevent confused-deputy access, restrictsns:Subscribeto known authorized accounts, and subscribe HTTPS-only endpoints so only authorized personnel receive registration status details.Input validation. Validate all user inputs (E.164 for phones, URL scheme allowlist, length checks) before passing them to APIs.
AWS security references. These recommendations follow AWS security best practices — see IAM Best Practices for least-privilege and ephemeral credentials, and AWS KMS Best Practices for encrypting CloudTrail logs and CloudWatch Log groups.
Failure modes
| Error / symptom | Cause | Fix |
|---|---|---|
Registration REQUIRES_UPDATES | Field(s) denied | describe-registration-field-values → per-field DeniedReason → create-registration-version → re-populate ALL fields → resubmit. Rejection feedback may include generated guidance — read it |
| Registration stuck in REVIEWING | Reviews take days to months by type | Poll daily, not per-minute; give the user the current ETA from the live sources in registration-requirements-by-country |
| Sends show "NOTICE"/"Unverified" sender | Registration not yet COMPLETE | Wait for COMPLETE; only COMPLETE counts |
ConflictException editing a registration | Locked while REVIEWING | Wait for a terminal state, or discard the version |
| Number request fails with a registration error | ASSOCIATE_AFTER_COMPLETE type requires COMPLETE before purchase | Finish the registration first, then request-phone-number |
| Throughput stuck at default MPS after approval | MPS increases are not automatic | Separate Support request for MPS |
| Registration type name from a doc or memory rejected as invalid | Type names drift | Discover live via describe-registration-type-definitions — see registration-requirements-by-country |
Cleanup (destructive — confirm with the user first)
Registrations and any purchased identities persist until removed; purchased numbers bill monthly
while owned. To stop: delete-registration, and release-phone-number / release-sender-id
for acquired identities — all irreversible. Confirm with the user, and note released numbers may
not be recoverable.
aws pinpoint-sms-voice-v2 delete-registration --registration-id <REG_ID> --region <REGION>Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an MCP server
Security
What our scanner noticed· Low risk
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- AWS
- Publisher
- AWS (Official)
- Source
- aws/agent-toolkit-for-aws · skills/specialized-skills/customer-communications-skills/aws-sms-voice · commit 0a218f8
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- NOTICE (added by AutoGineer from NOTICE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by AWS.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download aws-sms-voice.zip