API Documentation
Navigation
Introduction
Welcome to the CocoCloud Signing API documentation. Our API allows you to programmatically sign IPA files using your own certificates or our enterprise certificates.
Base URL
All endpoints are served from: https://api.cococloud-signing.vip
Health Check
A public, unauthenticated endpoint for uptime monitoring. It also reports the name and current signing status of the latest enterprise certificate, so you can tell at a glance whether — and with which certificate — enterprise signing is available.
GET https://api.cococloud-signing.vip/health
Jiangsu Simcere Pharmaceutical Co.,Ltd — Revoked
curl https://api.cococloud-signing.vip/health
Example Response
{
"status": "ok",
"service": "cococloud-signing-api",
"enterprise_cert_name": "Jiangsu Simcere Pharmaceutical Co.,Ltd",
"enterprise_cert_status": "Revoked",
"time": "2026-08-08T19:17:50-04:00"
}
Authentication
All API requests require authentication. We support two methods:
| Method | How to Use | Recommended |
|---|---|---|
| Bearer Token | Authorization: Bearer <token> |
Recommended |
| Legacy API Key | X-API-Key: sk_... header, or ?sk_... query parameter |
Legacy |
Log In
Token Scopes
Bearer tokens can be restricted to one or more scopes when created (or edited later) in the Developer Dashboard. A request using a token without the required scope gets a 403 with an error naming the missing scope.
| Scope | Covers |
|---|---|
sign |
customsign, free-enterprise/sign, apps/{id}/sign, and the chunk-upload endpoints |
apps |
The whole App Library: list, view, upload, update, copy, download, delete |
certs |
Shared Enterprise Certs API, cert/p12/mobileprovision downloads, Certificate Checker, P12 Password Changer |
user |
Includes your email address in the GET /v1/me response. Without it, email comes back null. |
Tokens created before scopes existed keep unrestricted access (all scopes) automatically — nothing to do. New tokens have all four scopes checked by default; uncheck any you don't need. Legacy API Keys and browser-session auth are never scoped.
Error Response - Missing Scope
{
"error": "This token does not have the 'sign' scope."
}
HTTP Status: 403 Forbidden
CORS (Cross-Origin Requests)
If you are calling the API from a browser (JavaScript/frontend), you must add your domain to the allowed CORS origins in the Developer Dashboard. Without this, browser requests will be blocked by CORS policy.
Signing Quickstart
New to the API? This page shows you the fastest path from an unsigned IPA to a signed, installable app.
Step 1 — Choose a signing method
| Method | Endpoint | Best for | Counts vs quota |
|---|---|---|---|
| Free Enterprise | POST /v2/free-enterprise/sign |
Quick one-shot sign — no cert needed, uses our shared enterprise cert | Yes |
| Custom Sign | POST /v2/customsign |
One-shot sign with your own cert — upload IPA + P12 + mobileprovision in one request | Yes |
| App Library Sign | POST /v2/apps/{id}/sign |
Persistent apps you want to re-sign, share, or download later — stored in your file manager | Yes |
Path A — Sign with Free Enterprise Cert (one-shot)
The simplest path. No certificate needed — we use our shared enterprise certificate.
curl -X POST https://api.cococloud-signing.vip/v2/free-enterprise/sign \ -H "X-API-Key: YOUR_API_KEY" \ -F "[email protected]"
Response includes a download_url and an ota_url (itms-services://…) for direct on-device install.
Path B — Sign with Your Own Certificate (one-shot)
Upload your IPA, P12, and mobileprovision in a single request.
curl -X POST https://api.cococloud-signing.vip/v2/customsign \ -H "X-API-Key: YOUR_API_KEY" \ -F "[email protected]" \ -F "[email protected]" \ -F "[email protected]" \ -F "password=YourP12Password"
user_cert_id — no file upload needed on future requests.
curl -X POST https://api.cococloud-signing.vip/v2/customsign \ -H "X-API-Key: YOUR_API_KEY" \ -F "[email protected]" \ -F "user_cert_id=YOUR_SAVED_CERT_ID"
Path C — App Library: Upload → Sign → Share (3 steps)
Best for apps you want to keep, re-sign later, or share a download link for. The signed file stays in your file manager permanently.
STEP 1 — Upload the IPA
curl -X POST https://api.cococloud-signing.vip/v2/apps/upload \ -H "X-API-Key: YOUR_API_KEY" \ -F "[email protected]" \ -F "access_status=0" \ -F "expiry_duration=30d"
Save the data.id from the response — you need it for the next steps.
STEP 2 — Sign the app
# Sign with enterprise cert (simplest) curl -X POST https://api.cococloud-signing.vip/v2/apps/APP_ID/sign \ -H "X-API-Key: YOUR_API_KEY" # — OR — sign with your own cert curl -X POST https://api.cococloud-signing.vip/v2/apps/APP_ID/sign \ -H "X-API-Key: YOUR_API_KEY" \ -F "user_cert_id=YOUR_SAVED_CERT_ID"
The sign response includes the updated app object with ota_url, plist_url, and download_url.
STEP 3 — Get a shareable download link
curl -X POST "https://api.cococloud-signing.vip/v2/apps/APP_ID/download-link?expires=18000" \ -H "X-API-Key: YOUR_API_KEY"
Returns a signed URL valid for up to 5 hours. Anyone with the URL can download the IPA — no API key needed.
Common Signing Options
These parameters work across all three signing methods:
bundleId— Override bundle identifier (e.g.com.mycompany.myapp)bundleName— Override the display namebundle_version— Override version string (e.g.2.1.0)bypassapplerevokes/random_bundle_id— Append a random suffix to the bundle ID to bypass revocation checksremove_prov— Strip the embedded mobileprovision from the signed IPAipa_compression— Zip compression level for the output IPA,0-9(0 = store/no compression, 9 = max compression). Defaults to0for the fastest sign time.
Plans & Limits
The API enforces several limits based on your account plan. These apply to all signing and App Library endpoints.
| Plan | Max File Size | Storage Quota | File Retention | Signing Requests | Cert Downloads | Copy to Library | AltStore Repos |
|---|---|---|---|---|---|---|---|
| Standard / Free | 3.95 GB | 5.00 GB | 190 days | 5,000 / Month | Primary MP Only | Not Available | 1 repo · 25.00 GB/mo |
| Pro Member | Unlimited | Unlimited | Unlimited | Unlimited | All Files | Available | Unlimited repos & bandwidth |
Storage Quota: The total size of all non-expired files in your App Library counts against your quota. Uploads that would exceed it are rejected with HTTP 413. Deleting or letting files expire frees space.
Signing Requests: The 5,000/month limit is shared across Custom Signing, Free Enterprise Signing, and App Library sign (/v2/apps/{id}/sign). Limits reset automatically on the 1st of each month at midnight.
Copy to Library: Pro-only, via
POST /v2/apps/{id}/copy or the "Copy to My Library" button on any public share page. The source app's owner can also disable it entirely (Allow Copy to Library toggle in their file manager), which overrides your plan.
AltStore Repos: Standard users get 1 persistent AltStore/AltSource repo (https://cococloud-signing.vip/user/repos) capped at 25.00 GB of app download bandwidth per month, pooled across all your repos. Pro users can create unlimited repos with unlimited bandwidth. Bandwidth resets automatically on the 1st of each month at midnight, same as the signing limit above.
Pro Feature: Mobileprovision Selection
The "Cert Downloads" restriction applies to both the Web UI and API:
- Standard Users: Restricted to primary mobileprovision only (Web UI & API)
- Pro Users: Can access all mobileprovision files and use the enterprise_mp_id parameter in the Free Enterprise Signing API
Programmatic Plan Detection
You can programmatically check your plan status and limits by inspecting the response headers of any API request:
X-Plan-Type: Returns Pro or StandardX-Plan-Limit: Returns your upload limit (e.g., 3.95 GB standard, Unlimited Pro)
Custom Signing API
Use this endpoint to sign IPA files with your own Certificate (.p12) and Provisioning Profile.
Limit: Standard users are limited to 5,000 requests per month.
Endpoint
POST https://api.cococloud-signing.vip/v2/customsign
Authentication
Include your API Key in the request header:
X-API-Key: YOUR_API_KEY
Parameters
You can now sign using a certificate already saved to your CocoCloud account by passing
user_cert_id instead of uploading cert and provision files. The platform securely retrieves and decrypts your certificate server-side — no file uploads needed.
| Option | Parameters Required |
|---|---|
| Saved certificate New | user_cert_id — ID of a certificate saved in your account |
| Upload files | cert (file) + provision (file) |
ipa: The IPA file or direct download URL (Required)user_cert_id: ID of a certificate saved to your account — replacescert+provisionNewcert: The Certificate (.p12) file — required if not usinguser_cert_idprovision: The Provisioning Profile — required if not usinguser_cert_idpassword: Certificate Password — optional when usinguser_cert_id(auto-resolved from your saved cert)bundleId: New Bundle ID (Optional)bundleName: New Bundle Name (Optional)bundle_version: New Bundle Version (e.g. '1.0.0') (Optional)random_bundle_id: Set to 'true' or '1' to append a random suffix to the bundle ID (Revoke Bypass) (Optional)remove_prov: Set to 'true' or '1' to remove the embedded mobileprovision file (Optional)ipa_compression: Zip compression level for the output IPA, 0-9 (Optional, default: 0 — fastest, no compression)
Example Request (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/customsign \ -H "X-API-Key: YOUR_API_KEY" \ -F "[email protected]" \ -F "[email protected]" \ -F "[email protected]" \ -F "password=secret" \ -F "random_bundle_id=1" \ -F "bundle_version=1.0.0"
Example Request with URL (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/customsign \ -H "X-API-Key: YOUR_API_KEY" \ -F "ipa=https://example.com/app.ipa" \ -F "[email protected]" \ -F "[email protected]" \ -F "password=secret"
Example Request with Saved Certificate (cURL) New
Use a certificate saved to your CocoCloud account. No file uploads needed — the platform handles everything.
curl -X POST https://api.cococloud-signing.vip/v2/customsign \ -H "X-API-Key: YOUR_API_KEY" \ -F "ipa=https://example.com/app.ipa" \ -F "user_cert_id=1" \ -F "random_bundle_id=1"
Example Response
{
"success": true,
"jobId": "6982c42f673c8",
"message": "IPA signed successfully",
"downloadUrl": "https://cococloud-signing.vip/storage/signed/6982c42f673c8_app.ipa",
"manifestUrl": "https://cococloud-signing.vip/storage/signed/6982c42f673c8_app.plist",
"itmsServicesUrl": "itms-services://?action=download-manifest&url=https%3A%2F%2Fcococloud-signing.vip%2Fstorage%2Fsigned%2F6982c42f673c8_app.plist",
"installUrl": "https://cococloud-signing.vip/ota/6982c42f673c8_app.plist",
"signingTime": "0.12s",
"performance": "⚡ Lightning Fast",
"appInfo": {
"bundleId": ".fj9prv",
"bundleName": "Noir",
"bundleVersion": "1.0.0"
},
"appSize": {
"input": "14.21 MB",
"output": "14.22 MB"
}
}
https:// links (e.g. Discord, Telegram, web buttons). It only works for files signed on this platform.
Error Response
{
"error": "File size exceeds your plan limit (3.95 GB). Please upgrade to Pro."
}
App Library API
The App Library lets you upload, manage, sign, and copy IPA files through the API. Unlike the one-shot signing endpoints, apps stored here are persistent and appear in your file manager, and can be re-signed at any time.
Pro apps never expire by default (set expiry_duration on upload for a shorter one). Standard-tier apps always expire — 190 days by default, or sooner if you set a shorter expiry_duration.
https://api.cococloud-signing.vip/v2/apps —
All endpoints require authentication (Bearer token or API key).
| Method | Endpoint | Description |
|---|---|---|
| POST | /v2/apps/upload | Upload an IPA (no signing) |
| GET | /v2/apps | List your apps |
| GET | /v2/apps/{id} | Get one app |
| GET | /v2/apps/{id}/download | Download the IPA (auth or signed URL) |
| POST | /v2/apps/{id}/download-link | Generate a temporary shareable download link (max 5h) |
| POST | /v2/apps/{id}/sign | Sign an app in the library |
| POST | /v2/apps/{id}/copy | Copy a public shared app into your library (Pro only) |
| PATCH | /v2/apps/{id} | Update app metadata / expiry |
| DELETE | /v2/apps/{id} | Delete an app and its files |
POST /v2/apps/upload — Upload IPA
Stores an IPA in your library and parses its metadata (app name, bundle ID, version, icon). The app is not signed.
Parameters
iparequired: IPA file upload or direct download URL or useipa_chunk_upload_idfor large filesaccess_status:1(public, default) /0(private — only visible to you)expiry_duration:1h/6h/1d/3d/7d/30d— omit for permanent (Pro only; standard users are capped at plan max)description: optional, shown on the public share page — max 1000 characterspassword: optional — password-protects the share page (max 255 characters; ignored if password protection is disabled for your plan)allow_download:true(default) /falseallow_ota_install:true(default) /false
Example (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/apps/upload \ -H "X-API-Key: YOUR_API_KEY" \ -F "[email protected]" \ -F "access_status=1" \ -F "expiry_duration=7d"
Example Response HTTP 201
{
"success": true,
"data": {
"id": "abc123xyz12345",
"name": "abc123xyz12345_MyApp",
"description": null,
"app_name": "My Application",
"bundle_id": "com.example.myapp",
"version": "2.1.0",
"size": 12345678,
"size_label": "11.77 MB",
"extension": "ipa",
"is_signed": false,
"signed_at": null,
"signed_with_cert_name": null,
"signed_with_cert_type": null,
"is_revoked": false,
"expiry_at": "2026-08-15T19:17:50-04:00",
"is_expired": false,
"allow_download": true,
"allow_ota_install": true,
"allow_copy_to_library": true,
"has_password": false,
"access_status": 1,
"icon_url": "https://cococloud-signing.vip/storage/icons/uuid.png",
"download_url": "https://api.cococloud-signing.vip/v2/apps/abc123xyz12345/download",
"ota_url": null,
"plist_url": null,
"share_url": "https://cococloud-signing.vip/abc123xyz12345",
"created_at": "2026-08-08T19:17:50-04:00"
}
}
GET /v2/apps — List Apps
Query Parameters
page: Page number (default: 1)per_page: Results per page, max 100 (default: 20)signed_only:trueto return only signed appsinclude_expired:trueto include expired appscert_type: Filter bysaved,enterprise, orcustom
curl "https://api.cococloud-signing.vip/v2/apps?signed_only=true&per_page=10" \ -H "X-API-Key: YOUR_API_KEY"
Example Response
{
"success": true,
"data": [ { ...app object... }, ... ],
"meta": {
"total": 42,
"per_page": 20,
"current_page": 1,
"last_page": 3
}
}
GET /v2/apps/{id} — Get App
Returns the full app object. The id is the shared_id returned by upload / list.
curl "https://api.cococloud-signing.vip/v2/apps/abc123xyz12345" \ -H "X-API-Key: YOUR_API_KEY"
GET /v2/apps/{id}/download — Download IPA
Streams the IPA file directly. Accepts either your API key or a pre-signed URL generated by POST /v2/apps/{id}/download-link.
curl "https://api.cococloud-signing.vip/v2/apps/abc123xyz12345/download" \ -H "X-API-Key: YOUR_API_KEY" \ -L -O -J
POST /v2/apps/{id}/download-link — Generate Download Link
Returns a temporary signed URL that lets anyone download the IPA without an API key — useful for sharing or automating installs.
Parameters
expires: Lifetime in seconds. Default3600(1 hour). Maximum18000(5 hours).
Example (cURL)
curl -X POST "https://api.cococloud-signing.vip/v2/apps/abc123xyz12345/download-link?expires=7200" \ -H "X-API-Key: YOUR_API_KEY"
Example Response HTTP 200
{
"success": true,
"url": "https://cococloud-signing.vip/api/v2/apps/abc123xyz12345/download?expires=...&signature=...",
"expires_at": "2026-08-08T20:17:50-04:00",
"expires_in": 3600
}
The signed URL is valid until expires_at. Anyone with the URL can download the file — treat it like a temporary password.
POST /v2/apps/{id}/sign — Sign App
Signs an IPA already in your library. Uses the same certificate options as the other signing endpoints. The FileEntry is updated in-place by default; pass output_type=copy to create a new entry and keep the original.
Certificate Options (choose one)
| Option | Parameters |
|---|---|
| Enterprise cert (default) | enterprise_cert_id (optional), enterprise_mp_id (optional, Pro) |
| Saved cert | user_cert_id (ID from your saved certificates) |
| Custom cert upload | cert (file), provision (file), password |
Signing Options
bundleId: Override bundle identifier (Optional)bundleName: Override display name (Optional)bundle_version: Override version string (Optional)bypassapplerevokes:1to append random suffix to bundle ID (Optional)remove_prov:1to strip embedded mobileprovision (Optional)ipa_compression: Zip compression level for the output IPA, 0-9 (Optional, default: 0 — fastest, no compression)output_type:copyto leave original untouched and create a new entry (Optional)
Example — Sign with Enterprise Cert (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/apps/abc123xyz12345/sign \ -H "X-API-Key: YOUR_API_KEY"
Example — Sign with Custom Cert (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/apps/abc123xyz12345/sign \ -H "X-API-Key: YOUR_API_KEY" \ -F "[email protected]" \ -F "[email protected]" \ -F "password=secret" \ -F "bypassapplerevokes=1"
Example Response
{
"success": true,
"signing_time": "0.14s",
"data": {
"id": "abc123xyz12345",
"app_name": "My Application",
"bundle_id": "com.example.myapp",
"version": "2.1.0",
"is_signed": true,
"signed_at": "2026-08-08T19:17:50-04:00",
"signed_with_cert_name": "Enterprise Cert A",
"signed_with_cert_type": "enterprise",
"ota_url": "itms-services://?action=download-manifest&url=...",
"plist_url": "https://cococloud-signing.vip/storage/users/1/signed/abc123.plist",
"download_url": "https://api.cococloud-signing.vip/v2/apps/abc123xyz12345/download",
...
}
}
POST /v2/apps/{id}/copy — Copy a Shared App
Clones any public shared app into your own library — the same action as the "Copy to My Library" button on a share page. Unlike every other /v2/apps/{id} endpoint, {id} here is any public shared_id, not necessarily one you own.
Parameters
password: required only if the source app is password-protected — unlocks the source, it is not the password for your copyexpiry_duration:1h/6h/1d/3d/7d/30d— omit for permanent. Applied through the same tier-aware system as uploads and signing — never hardcoded, always capped to your actual plan limitnew_password: optional — password-protects your new copy's share page (max 255 characters; ignored if password protection is disabled for your plan)
Example (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/apps/{shared_id}/copy \
-H "X-API-Key: YOUR_API_KEY" \
-d "expiry_duration=7d" \
-d "new_password=mySecret123"
Example Response HTTP 201
{
"success": true,
"data": { ...app object, now owned by you... }
}
Error Responses
403 {"error": "...", "pro_required": true}— you are not a Pro member403— the owner disabled copying or downloads for this app422— this app is already yours413— copying it would exceed your storage quota
PATCH /v2/apps/{id} — Update App
Update metadata or expiry. All fields optional — only send what you want to change.
name: Display name (string)description: shown on the public share page — max 1000 charactersexpiry_at: ISO-8601 datetime, ornullto never expire (Pro only)allow_download:true/falseallow_ota_install:true/falseallow_copy_to_library:true/false— lets Pro members copy this app into their own library from the share page (default: true)access_status:1(public) /0(private)password: set/change the share-page password (max 255 characters); send an empty string to remove it (ignored if password protection is disabled for your plan)
curl -X PATCH https://api.cococloud-signing.vip/v2/apps/abc123xyz12345 \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"expiry_at": "2026-09-07T19:17:50-04:00", "allow_download": true}'
DELETE /v2/apps/{id} — Delete App
Permanently deletes the app and its associated IPA / plist files from storage.
curl -X DELETE https://api.cococloud-signing.vip/v2/apps/abc123xyz12345 \ -H "X-API-Key: YOUR_API_KEY"
Response
{ "success": true, "message": "App deleted." }
Common Error Responses
| Status | Meaning |
|---|---|
401 | Missing or invalid API key / token |
404 | App not found (or belongs to another user) |
410 | App has expired |
422 | Validation error (see error field) |
429 | Monthly request limit reached |
500 | Signing or server error |
Certificate Checker API
Validate iOS certificates (.p12) and provisioning profiles (.mobileprovision) with real-time certificate status checking.
Endpoint
POST https://api.cococloud-signing.vip/v2/certcheckerstatus
Authentication
Include your API Key in the request header:
X-API-Key: YOUR_API_KEY
Parameters
file: The certificate (.p12) or provisioning profile (.mobileprovision) file, or a direct download URL (Required)password: Certificate password (Required for .p12 files, ignored for .mobileprovision)
Example Request - P12 Certificate (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/certcheckerstatus \\ -H "X-API-Key: YOUR_API_KEY" \\ -F "[email protected]" \\ -F "password=your_password"
Example Request - MobileProvision (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/certcheckerstatus \\ -H "X-API-Key: YOUR_API_KEY" \\ -F "[email protected]"
Example Request - P12 from URL (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/certcheckerstatus \\ -H "X-API-Key: YOUR_API_KEY" \\ -F "file=https://example.com/certificate.p12" \\ -F "password=your_password"
Example Request - MobileProvision from URL (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/certcheckerstatus \\ -H "X-API-Key: YOUR_API_KEY" \\ -F "file=https://example.com/profile.mobileprovision"
Example Response - P12 File
{
"success": true,
"data": {
"certificate_info": {
"subject": {
"userID": "VD7465CKUB",
"commonName": "iPhone Distribution: Jiangsu Simcere Pharmaceutical Co.,Ltd",
"organizationalUnitName": "VD7465CKUB",
"organizationName": "Jiangsu Simcere Pharmaceutical Co.,Ltd",
"countryName": "US"
},
"issuer": {
"commonName": "Apple Worldwide Developer Relations Certification Authority",
"organizationalUnitName": "G3",
"organizationName": "Apple Inc.",
"countryName": "US"
},
"validity_period": {
"valid_from": "2025-03-07T09:22:42+00:00",
"valid_to": "2028-03-06T09:22:41+00:00"
},
"fingerprints": {
"sha256": "82185c7f97d1e39c95ce905535f98a2b5a96f920fe8ecc5279f0697a6f0670d0"
}
},
"certificate_status": {
"status": "Revoked"
},
"entitlements": "Entitlements are not applicable for p12 files",
"type": "N/A"
},
"message": "Certificate validated successfully"
}
Example Response - MobileProvision File
{
"success": true,
"message": "Certificate validated successfully",
"data": {
"certificate_info": {
"subject": { ... },
"issuer": { ... },
"validity_period": { ... },
"fingerprints": { ... }
},
"certificate_status": {
"status": "Revoked",
"reason": "cessationOfOperation (5)",
"reason_details": "The certificate is no longer needed",
"revocation_time": "2024-11-19T02:05:29Z"
},
"entitlements": {
"Push Notifications": { "status": "active" },
"App Groups": { "status": "active" },
"Associated Domains": { "status": "active" }
},
"type": "Enterprise Certificate",
"mobileprovision_info": {
"Name": "iOS Team Inhouse Provisioning Profile",
"UUID": "cc32b862-80f8-4aa3-bfca-54908f3533eb",
"TeamName": "Example Team",
"ExpirationDate": "2026-04-09T12:50:26"
}
}
}
Dual File Mode - NEW!
Check both P12 and mobileprovision files simultaneously by providing a mobileprovision parameter!
Parameters (Dual Mode)
file: P12 certificate file or URL (Required)mobileprovision: Mobileprovision file or URL (Required for dual mode)password: Password for P12 (Optional)
Example Request - Dual Mode (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/certcheckerstatus \\ -H "X-API-Key: YOUR_API_KEY" \\ -F "[email protected]" \\ -F "password=your_password" \\ -F "[email protected]"
Example Response - Dual Mode
{
"success": true,
"message": "Both files validated successfully",
"p12_certificate": {
"certificate_info": { ... },
"certificate_status": { "status": "Signed" },
"entitlements": "Not applicable for p12",
"type": "N/A"
},
"mobileprovision": {
"certificate_info": { ... },
"certificate_status": { "status": "Signed" },
"entitlements": {
"Push Notifications": { "status": "active" }
},
"type": "Enterprise Certificate",
"mobileprovision_info": {
"Name": "iOS Team Inhouse Provisioning Profile",
"UUID": "cc32b862-80f8-4aa3-bfca-54908f3533eb"
}
}
}
Certificate Status Values
Signed: Certificate is valid and activeRevoked: Certificate has been revoked by AppleUnknown: OCSP status could not be determined
Error Response
{
"success": false,
"message": "Error description"
}
P12 Password Changer API
Change the password of a P12 certificate file. Upload a certificate or provide a URL, and get back a new P12 file with the updated password.
Endpoint
POST https://api.cococloud-signing.vip/v2/p12passwordchanger
Authentication
Include your API Key in the request header:
X-API-Key: YOUR_API_KEY
Parameters
file: The P12 certificate file or direct download URL (Required)old_password: Current/old password of the P12 file (Required, use empty string if no password)new_password: New password to set (Required)
Example Request - File Upload (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/p12passwordchanger \\ -H "X-API-Key: YOUR_API_KEY" \\ -F "[email protected]" \\ -F "old_password=current_password" \\ -F "new_password=new_secure_password" \\ --output certificate_new_password.p12
Example Request - From URL (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/p12passwordchanger \\ -H "X-API-Key: YOUR_API_KEY" \\ -F "file=https://example.com/certificate.p12" \\ -F "old_password=current_password" \\ -F "new_password=new_secure_password" \\ --output certificate_new_password.p12
Response
On success, the API returns the new P12 file with the changed password as a binary download. The response includes custom headers:
Content-Type: application/x-pkcs12Content-Disposition: attachment; filename="certificate_new_password.p12"X-Success: trueX-Message: Password changed successfully
Error Response
{
"success": false,
"message": "Failed to change password",
"error": "Error details"
}
Free Enterprise Signing API
Jiangsu Simcere Pharmaceutical Co.,Ltd
Status: Revoked
Sign IPA files using our pre-configured enterprise certificate. This is the simplest way to sign apps.
Limit: Standard users are limited to 5,000 requests per month.
Endpoint
POST https://api.cococloud-signing.vip/v2/free-enterprise/sign
Authentication
Include your API Key in the request header:
X-API-Key: YOUR_API_KEY
Parameters
ipa: The IPA file or direct download URL (Required)bundleId: New Bundle ID (Optional)bundleName: New Bundle Name (Optional)bundle_version: New Bundle Version (e.g. '1.0.0') (Optional)random_bundle_id: Set to 'true' or '1' to append a random suffix to the bundle ID (Revoke Bypass) (Optional)remove_prov: Set to 'true' or '1' to remove the embedded mobileprovision file (Optional)ipa_compression: Zip compression level for the output IPA, 0-9 (Optional, default: 0 — fastest, no compression)-
enterprise_mp_id: Mobileprovision file ID to use for signing (Optional) Pro Feature
Pro Feature: Mobileprovision Selection
Pro users can specify which mobileprovision file to use via the enterprise_mp_id parameter. This is useful for:
- Switching to alternative profiles if one gets blacklisted by Apple
- Using different entitlements for different apps
Example Request (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/free-enterprise/sign \ -H "X-API-Key: YOUR_API_KEY" \ -F "[email protected]" \ -F "random_bundle_id=1"
Example Request with URL (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/free-enterprise/sign \\ -H "X-API-Key: YOUR_API_KEY" \\ -F "ipa=https://example.com/app.ipa"
Example Request with Mobileprovision Selection (Pro Users)
curl -X POST https://api.cococloud-signing.vip/v2/free-enterprise/sign \\ -H "X-API-Key: YOUR_API_KEY" \\ -F "[email protected]" \\ -F "enterprise_mp_id=3"Use the Shared Enterprise Certs API to get available mobileprovision IDs.
Example Response
{
"success": true,
"jobId": "6982c4a2ed391",
"message": "IPA signed successfully",
"downloadUrl": "https://cococloud-signing.vip/storage/signed/6982c4a2ed391_app.ipa",
"manifestUrl": "https://cococloud-signing.vip/storage/signed/6982c4a2ed391_app.plist",
"itmsServicesUrl": "itms-services://?action=download-manifest&url=https%3A%2F%2Fcococloud-signing.vip%2Fstorage%2Fsigned%2F6982c4a2ed391_app.plist",
"installUrl": "https://cococloud-signing.vip/ota/6982c4a2ed391_app.plist",
"signingTime": "0.09s",
"performance": "⚡ Lightning Fast",
"appInfo": {
"bundleId": "nl.jeffreykuiken.NoirApp",
"bundleName": "Noir",
"bundleVersion": "2025.2.6"
},
"appSize": {
"input": "14.21 MB",
"output": "14.21 MB"
},
"certificate_info": {
"cert_name": "Jiangsu Simcere Pharmaceutical Co.,Ltd",
"cer_status": "Revoked",
"revoked_from": null
}
}
Error Response - File Size Limit
{
"error": "File size exceeds your plan limit (3.95 GB). Please upgrade to Pro."
}
Error Response - Unauthorized Mobileprovision
{
"error": "Standard users can only use the primary mobileprovision. Please upgrade to Pro for access to additional profiles."
}
HTTP Status: 403 Forbidden
Error Response - Invalid Mobileprovision ID
{
"error": "Invalid mobileprovision ID"
}
HTTP Status: 404 Not Found
Custom Signing API (No Auth) New
Same as Custom Signing, but callable with no API key at all — no account, no Bearer token, no X-API-Key header.
Endpoint
POST https://api.cococloud-signing.vip/v2/noauth/customsign
Authentication
None. Do not send an Authorization or X-API-Key header.
Parameters
ipa: The IPA file or direct download URL (Required)cert: The Certificate (.p12) file (Required)provision: The Provisioning Profile (Required)password: Certificate Password (Optional)bundleId: New Bundle ID (Optional)bundleName: New Bundle Name (Optional)bundle_version: New Bundle Version (e.g. '1.0.0') (Optional)random_bundle_id: Set to 'true' or '1' to append a random suffix to the bundle ID (Revoke Bypass) (Optional)remove_prov: Set to 'true' or '1' to remove the embedded mobileprovision file (Optional)ipa_compression: Zip compression level for the output IPA, 0-9 (Optional, default: 0 — fastest, no compression)
Example Request — Direct File Upload (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/noauth/customsign \ -F "[email protected]" \ -F "[email protected]" \ -F "[email protected]" \ -F "password=secret"
Example Request — IPA via URL (cURL)
ipa also accepts a direct download URL instead of an uploaded file — cert and provision must still be uploaded files.
curl -X POST https://api.cococloud-signing.vip/v2/noauth/customsign \ -F "ipa=https://example.com/app.ipa" \ -F "[email protected]" \ -F "[email protected]" \ -F "password=secret"
Example Response
{
"success": true,
"id": "75987953",
"install_url": "https://cococloud-signing.vip/en/noauthsigning/75987953",
"message": "IPA signed successfully. Share install_url — download and OTA install are free there for everyone; non-Pro visitors just see the usual ads (with an optional ad-code to hide them for 5 minutes).",
"signingTime": "0.31s",
"expiresAt": "2026-08-09T01:17:50-04:00",
"appInfo": {
"bundleId": "com.example.app",
"bundleName": "Example App",
"bundleVersion": "1.0.0"
},
"appSize": {
"input": "14.21 MB",
"output": "14.21 MB"
},
"certificate_info": {
"signing_method": "custom",
"cert_name": "iPhone Distribution: Example Corp",
"cert_status": "Signed"
}
}
cert_name and cert_status are extracted from the uploaded cert at sign time (same validation used by the Certificate Checker API). cert_status may be null if it could not be determined.
Free Enterprise Signing API (No Auth) New
Same as Free Enterprise Signing, but callable with no API key at all — signs against our shared enterprise certificate, no account required.
Endpoint
POST https://api.cococloud-signing.vip/v2/noauth/free-enterprise/sign
Authentication
None. Do not send an Authorization or X-API-Key header.
Parameters
ipa: The IPA file or direct download URL (Required)enterprise_cert_id: Use a specific enterprise certificate instead of the latest usable one (Optional)bundleId: New Bundle ID (Optional)bundleName: New Bundle Name (Optional)bundle_version: New Bundle Version (e.g. '1.0.0') (Optional)random_bundle_id: Set to 'true' or '1' to append a random suffix to the bundle ID (Revoke Bypass) (Optional)remove_prov: Set to 'true' or '1' to remove the embedded mobileprovision file (Optional)ipa_compression: Zip compression level for the output IPA, 0-9 (Optional, default: 0 — fastest, no compression)
Example Request — Direct File Upload (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/noauth/free-enterprise/sign \ -F "[email protected]" \ -F "random_bundle_id=1"
Example Request — IPA via URL (cURL)
ipa also accepts a direct download URL instead of an uploaded file.
curl -X POST https://api.cococloud-signing.vip/v2/noauth/free-enterprise/sign \ -F "ipa=https://example.com/app.ipa" \ -F "random_bundle_id=1"
Example Response
{
"success": true,
"id": "75987953",
"install_url": "https://cococloud-signing.vip/en/noauthsigning/75987953",
"message": "IPA signed successfully. Share install_url — download and OTA install are free there for everyone; non-Pro visitors just see the usual ads (with an optional ad-code to hide them for 5 minutes).",
"signingTime": "0.09s",
"expiresAt": "2026-08-09T01:17:50-04:00",
"appInfo": {
"bundleId": "com.example.app",
"bundleName": "Example App",
"bundleVersion": "1.0.0"
},
"appSize": {
"input": "14.21 MB",
"output": "14.21 MB"
},
"certificate_info": {
"signing_method": "enterprise",
"cert_name": "Jiangsu Simcere Pharmaceutical Co.,Ltd",
"cert_status": "Revoked"
}
}
cert_status reflects the enterprise certificate's status at the moment of signing.
Me (Account Info)
Look up who a Bearer token or API key belongs to, whether the account is Pro, and its current signing/storage limits and usage. Handy for clients that want to show account status without hardcoding your plan.
Endpoint
GET https://api.cococloud-signing.vip/v1/me
Authentication
Use a Bearer token (recommended) or legacy API key:
- Bearer Token:
Authorization: Bearer <token> - Legacy: Include your API Key as a query parameter:
?YOUR_API_KEY
Example Request with Bearer Token (cURL)
curl -X GET "https://api.cococloud-signing.vip/v1/me" \ -H "Authorization: Bearer YOUR_TOKEN"
Example Request with Legacy Key (cURL)
curl -X GET "https://api.cococloud-signing.vip/v1/me?sk_YOUR_API_KEY"
Example Response
{
"success": true,
"user": {
"name": "Jane Doe",
"username": "janedoe",
"email": "[email protected]",
"member_since": "2026-01-15T10:30:00+00:00"
},
"is_pro": false,
"pro": null,
"auth": {
"type": "bearer",
"token_name": "My CI Token",
"scopes": ["sign", "apps"]
},
"limits": {
"signing": {
"unlimited": false,
"monthly_limit": 5000,
"used_this_month": 42,
"remaining_this_month": 4958,
"resets_at": "2026-08-01T00:00:00+00:00"
},
"upload": {
"max_file_size_bytes": 2147483648,
"max_file_size_label": "2.00 GB"
},
"storage": {
"limit_bytes": 5368709120,
"limit_label": "5.00 GB",
"used_bytes": 269143231,
"remaining_bytes": 5099565889
}
},
"stats": {
"apps_count": 3,
"files_count": 5,
"certificates_count": 1,
"api_tokens_count": 2
},
"api_banned": false,
"api_ban_reason": null
}
Response Fields
user.email: Only included when the token has theuserscope (legacy API keys and session auth always get it, since they\'re never scoped). Otherwisenull.is_pro: Boolean. Whether the account currently has an active Pro license.pro.expires_at: ISO-8601 expiry of the Pro license, ornullif not Pro.auth.type: How this request authenticated —bearerorlegacy.auth.token_name/auth.scopes: Only populated for Bearer tokens;nullfor legacy API keys.limits.signing.unlimited:truefor Pro accounts (no monthly signing cap).limits.signing.monthly_limit/used_this_month/remaining_this_month: Standard-plan signing quota,nullwhen unlimited.limits.signing.resets_at: When the monthly signing counter resets (1st of next month).limits.upload.max_file_size_bytes: Largest single file this account may upload/sign,nullif unlimited.limits.storage: Total App Library storage quota, current usage, and bytes remaining.limit_bytes/remaining_bytesarenullwhen unlimited.stats.apps_count: Number of non-expired IPAs in the App Library.stats.files_count: Number of non-expired files of any type owned by this account.stats.certificates_count: Number of custom certificates uploaded by this account.stats.api_tokens_count: Number of active Bearer tokens on this account.api_banned/api_ban_reason: Whether the account is currently banned from the API.
Error Response
{
"error": "Authentication required. Use Bearer token or API key."
}
Webhooks
Webhooks allow you to receive real-time notifications about events happening in your account. You can configure webhooks for Discord, Telegram, or a generic HTTP endpoint.
Supported Events
| Event Name | Description |
|---|---|
cert.uploaded |
Triggered when you upload a new personal certificate. |
cert.revoked |
Triggered when one of your personal certificates is revoked. |
cert.deleted |
Triggered when you delete a personal certificate. |
enterprise_cert.available |
Triggered when a new shared enterprise certificate is uploaded by admins. |
enterprise_cert.revoked |
Triggered when a shared enterprise certificate is revoked. |
enterprise_mp.available |
Triggered when a new mobile provision is added to a shared enterprise certificate. Includes Pro details. |
Payload Structure
The payload structure depends on the webhook type (Discord, Telegram, or Generic). Below is the generic JSON payload format:
Example Payload: Enterprise Certificate Available
{
"event": "enterprise_cert.available",
"data": {
"title": "New Enterprise Certificate Available",
"message": "A new shared certificate 'Apple Inc' is now available for signing.",
"color": 5763719,
"fields": {
"Certificate ID": 1,
"Certificate Name": "Apple Inc",
"Status": "Signed",
"Expiration Date": "2026-02-07T11:07:09+00:00",
"Available At": "2024-11-24 00:45:00",
"Signer URL": "https://cococloud-signing.vip/user/ipa-signer"
}
},
"timestamp": "2024-11-24T00:45:00.000000Z"
}
Example Payload: Enterprise Certificate Revoked
{
"event": "enterprise_cert.revoked",
"data": {
"title": "Enterprise Certificate Revoked",
"message": "The shared certificate 'Apple Inc' has been revoked. Please wait for a replacement.",
"color": 16711680,
"fields": {
"Certificate ID": 1,
"Certificate Name": "Apple Inc",
"Status": "Revoked",
"Reason": "Key Compromised",
"Revoked At": "2024-11-25 10:00:00"
}
},
"timestamp": "2024-11-25T10:00:00.000000Z"
}
Example Payload: Enterprise Mobile Provision Added
{
"event": "enterprise_mp.available",
"data": {
"title": "New Mobile Provision Available",
"message": "A new mobile provision file has been added to the certificate 'Apple Inc'.",
"color": 5763719,
"image": "https://cococloud-signing.vip/signing-imgs-status/signed.jpg",
"url": "https://cococloud-signing.vip/user/certificates/1",
"fields": {
"Certificate Name": "Apple Inc",
"Event": "Mobile Provision Added",
"Added At": "2024-11-26 15:30:00",
"Platform": "CocoCloud Signing 2.0",
"Mobile Provision Name": "iOS Team Provisioning Profile: com.example.app",
"UUID": "12345678-1234-1234-1234-1234567890ab",
"Team Name": "Apple Inc",
"Team Identifier": "ABCDE12345",
"Creation Date": "2024-11-26 15:00:00",
"Expiration Date": "2025-11-26 15:00:00",
"Time To Live": "365 days",
"App ID Name": "XC com example app"
}
},
"timestamp": "2024-11-26T15:30:00.000000Z"
}
Headers
We send the following headers with every webhook request:
User-Agent: CocoCloud-Webhook/1.0Content-Type: application/jsonX-Webhook-Event: The event name (e.g.,enterprise_cert.available)
Certificate Import via URL Parameters
Import certificates directly into your account by visiting a URL with certificate file locations. Perfect for automation and sharing certificate configurations.
How It Works
- Create a URL with certificate file locations as query parameters
- Visit the URL (login required if not authenticated)
- Certificate files are automatically downloaded and validated
- Certificate is imported into your "My Certificates" section
URL Format
https://cococloud-signing.vip/user/certificates?p12=P12_URL&mp=MP_URL&password=PASSWORD
Parameters
p12: Direct URL to P12 certificate file (Required)mp: Direct URL to mobileprovision file (Required)password: Certificate password (Optional)
- URLs must use HTTP or HTTPS protocols
- Files must be under 10MB each
- Download timeout is 30 seconds per file
- Certificates are validated before import
Example: Authenticated User
If you are already logged in, visit the URL and the certificate imports immediately:
https://cococloud-signing.vip/user/certificates?\ mp=https://example.com/profile.mobileprovision&\ p12=https://example.com/cert.p12&\ password=mycertpassword
Example: Unauthenticated User
If you are not logged in, you will be redirected to login. After successful login, the import happens automatically:
https://cococloud-signing.vip/user/certificates?\ mp=https://cdn.example.com/files/profile.mobileprovision&\ p12=https://cdn.example.com/files/certificate.p12&\ password=secret123
Use Cases
- Team Distribution: Share certificate links with team members for easy setup
- Automation: Generate import links programmatically after creating certificates
- Documentation: Include import links in setup guides and tutorials
- CI/CD Integration: Automatically import certificates from external storage
Response Messages
| Status | Message |
|---|---|
| Success | "Certificate 'Name' imported successfully" |
| Error | "Invalid URL format: ..." |
| Error | "Download failed: ..." |
| Error | "Certificate validation failed: ..." |
| Missing | "P12 certificate URL is required" |
| Missing | "Mobileprovision file URL is required" |
Certificate Import via Bundle API
Upload a .cocosigncert bundle - the same encrypted certificate bundle format CoCoSign (the iOS app) can create and read under Settings → Certificates, and the same format the standalone .cocosigncert Creator web tool builds. The bundle is decrypted, validated (revocation status comes back in the same response - no separate cert-check call needed), and added to your "My Certificates".
Endpoint
POST https://api.cococloud-signing.vip/v2/certificates/import-bundle
Authentication
Use a Bearer token (recommended) or legacy API key. A Bearer token needs the certs scope:
- Bearer Token:
Authorization: Bearer <token>(requires thecertsScope) - Legacy: Include your API Key in the request header:
X-API-Key: YOUR_API_KEY
Parameters
bundle: The .cocosigncert file (Required, multipart upload, max 10MB)passphrase: The bundle's passphrase - required only if it was exported encrypted. Omit entirely for an unencrypted bundle.
Example Request (cURL)
curl -X POST https://api.cococloud-signing.vip/v2/certificates/import-bundle \\ -H "Authorization: Bearer YOUR_TOKEN" \\ -F "[email protected]" \\ -F "passphrase=your-bundle-passphrase"
Example Response
{
"success": true,
"message": "Certificate 'My Signing Certificate' imported successfully",
"certificate": { "id": 123, "name": "My Signing Certificate", "...": "..." },
"details": {
"name": "My Signing Certificate",
"status": "Signed",
"ocsp": "Signed"
},
"extra_provisions_skipped": 0
}
Response Messages
| Status | Message |
|---|---|
| Success | "Certificate 'Name' imported successfully" |
| 422 | "This bundle is encrypted - a passphrase is required to open it." (passphrase_required: true) |
| 400 | "Incorrect passphrase, or this file is corrupted." (deliberately doesn't distinguish which) |
| 400 | "Certificate validation failed: ..." |
| 403 | "This token does not have the 'certs' scope." |