{"openapi":"3.1.0","info":{"title":"FreedomSwap API","version":"1.8.0","description":"Create an executable quote, create a swap, and track its public status. Use the backend-only SDK with one key ID and one shared secret."},"servers":[{"url":"/api/v1"}],"paths":{"/health":{"get":{"summary":"Read service availability","responses":{"200":{"description":"Service available"},"503":{"description":"Service temporarily unavailable"}}}},"/assets":{"get":{"summary":"List available assets and networks","responses":{"200":{"description":"Asset catalogue","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetCatalog"}}}},"503":{"description":"Assets temporarily unavailable"}}}},"/pairs":{"get":{"summary":"Read pair guidance and limits","description":"Omit query parameters for compact pair guidance. Provide sourceAsset and sourceNetwork together to get destination guidance for a selected source. Use POST /quotes for a current quote for a specific amount.","parameters":[{"name":"sourceAsset","in":"query","required":false,"description":"Source asset. Supply this together with sourceNetwork.","schema":{"type":"string"},"example":"BTC"},{"name":"sourceNetwork","in":"query","required":false,"description":"Source network. Supply this together with sourceAsset.","schema":{"type":"string"},"example":"BTC"}],"responses":{"200":{"description":"Pair guidance"},"400":{"description":"Both source parameters must be supplied together."},"503":{"description":"Pair guidance temporarily unavailable"}}}},"/quotes":{"post":{"summary":"Request one executable quote","description":"Returns one available quote for the requested pair and amount. Create the swap with its ID before expiresAt.","security":[{"partnerKeyId":[],"partnerUser":[],"partnerTimestamp":[],"partnerNonce":[],"partnerSignature":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequest"}}}},"responses":{"200":{"description":"Executable quote","content":{"application/json":{"schema":{"type":"object","required":["quote"],"properties":{"quote":{"$ref":"#/components/schemas/Quote"}}}}}},"400":{"description":"Invalid quote request"},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"description":"Pair, amount, or requested rate type unavailable"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"description":"Quotes temporarily unavailable"}}}},"/swaps":{"get":{"summary":"List swaps for the authenticated partner","security":[{"partnerKeyId":[],"partnerUser":[],"partnerTimestamp":[],"partnerNonce":[],"partnerSignature":[]}],"responses":{"200":{"description":"Swap list","content":{"application/json":{"schema":{"type":"object","required":["orders"],"properties":{"orders":{"type":"array","items":{"$ref":"#/components/schemas/Swap"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"summary":"Create a one-time swap","description":"Create a swap from an unexpired quote. For a retry-safe partner create, retain and resend the same Idempotency-Key with the identical request body. Wait until depositAddress is present before asking the customer to send funds.","security":[{"partnerKeyId":[],"partnerUser":[],"partnerTimestamp":[],"partnerNonce":[],"partnerSignature":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Caller-generated visible ASCII key, 1-255 characters. Reusing it with the same body replays the original response; reusing it with a different body returns 409.","schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[\\x21-\\x7e]{1,255}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwapRequest"}}}},"responses":{"202":{"description":"Queued swap and swap access token","content":{"application/json":{"schema":{"type":"object","required":["order","accessToken"],"properties":{"order":{"$ref":"#/components/schemas/Swap"},"accessToken":{"type":"string","readOnly":true}}}}}},"400":{"description":"Invalid swap request"},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"description":"Quote unavailable or expired, or the Idempotency-Key conflicts with a different request"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"description":"Swap creation temporarily unavailable"}}}},"/swaps/{id}":{"get":{"summary":"Read a swap","description":"Authenticate with the access token returned at creation or with signed partner credentials.","security":[{"swapAccessToken":[]},{"partnerKeyId":[],"partnerUser":[],"partnerTimestamp":[],"partnerNonce":[],"partnerSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Swap and public event timeline","content":{"application/json":{"schema":{"type":"object","required":["order","events"],"properties":{"order":{"$ref":"#/components/schemas/Swap"},"events":{"type":"array","items":{"$ref":"#/components/schemas/SwapEvent"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Not found"}}}},"/swaps/{id}/stream":{"get":{"summary":"Stream swap status","description":"Server-Sent Events for a swap access token.","security":[{"swapAccessToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"text/event-stream"},"401":{"description":"Access token required"}}}},"/permanent-routes/challenges":{"post":{"summary":"Create an ownership challenge","description":"Sign the returned challenge with the wallet that controls the settlement destination, then include that proof when creating the route.","security":[{"partnerKeyId":[],"partnerUser":[],"partnerTimestamp":[],"partnerNonce":[],"partnerSignature":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermanentRouteTarget"}}}},"responses":{"201":{"description":"Ownership challenge","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermanentChallenge"}}}},"400":{"description":"Invalid settlement target"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/permanent-routes":{"get":{"summary":"List permanent routes","security":[{"partnerKeyId":[],"partnerUser":[],"partnerTimestamp":[],"partnerNonce":[],"partnerSignature":[]}],"responses":{"200":{"description":"Permanent routes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermanentRouteList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"summary":"Create or recover a permanent route","description":"A reusable route remains bound to its verified settlement target.","security":[{"partnerKeyId":[],"partnerUser":[],"partnerTimestamp":[],"partnerNonce":[],"partnerSignature":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermanentRouteRequest"}}}},"responses":{"201":{"description":"Permanent route","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermanentRoute"}}}},"400":{"description":"Invalid route request"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Wallet ownership could not be verified","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Route cannot be created at this time","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Permanent routes temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/permanent-routes/{id}":{"get":{"summary":"Read a permanent route","security":[{"partnerKeyId":[],"partnerUser":[],"partnerTimestamp":[],"partnerNonce":[],"partnerSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Permanent route","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermanentRoute"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/permanent-routes/{id}/deposits":{"get":{"summary":"List deposits for a permanent route","description":"Each deposit includes confirmation progress and its public swap status when available.","security":[{"partnerKeyId":[],"partnerUser":[],"partnerTimestamp":[],"partnerNonce":[],"partnerSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Permanent-route deposits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermanentDepositList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/permanent-routes/{id}/expect-deposit":{"post":{"summary":"Register an expected deposit","security":[{"partnerKeyId":[],"partnerUser":[],"partnerTimestamp":[],"partnerNonce":[],"partnerSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Expectation window","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermanentDepositExpectation"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Permanent routes temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"swapAccessToken":{"type":"http","scheme":"bearer","description":"The access token returned once when a swap is created."},"partnerKeyId":{"type":"apiKey","in":"header","name":"x-freedomswap-key-id","description":"Partner credential identifier. The SDK adds this header."},"partnerUser":{"type":"apiKey","in":"header","name":"x-freedomswap-user","description":"Partner-controlled customer identifier."},"partnerTimestamp":{"type":"apiKey","in":"header","name":"x-freedomswap-timestamp","description":"Request timestamp. The SDK adds this header."},"partnerNonce":{"type":"apiKey","in":"header","name":"x-freedomswap-nonce","description":"Request nonce. The SDK adds this header."},"partnerSignature":{"type":"apiKey","in":"header","name":"x-freedomswap-signature","description":"Request signature generated with the backend-only shared secret. Partners receive exactly two static credentials: key ID and shared secret."}},"responses":{"Unauthorized":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Rate limit exceeded; retry after a delay","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"Asset":{"type":"object","required":["symbol","name","network","networkCode","icon"],"properties":{"symbol":{"type":"string"},"name":{"type":"string"},"network":{"type":"string"},"networkCode":{"type":"string"},"icon":{"type":"string"},"memoNeeded":{"type":"boolean"},"memoName":{"type":"string"}}},"AssetCatalog":{"type":"object","required":["currencyCount","assetNetworkCount","assets"],"properties":{"currencyCount":{"type":"integer"},"assetNetworkCount":{"type":"integer"},"assets":{"type":"array","items":{"$ref":"#/components/schemas/Asset"}}}},"QuoteRequest":{"type":"object","required":["sourceAsset","sourceNetwork","destinationAsset","destinationNetwork","sourceAmount","refundMode"],"properties":{"sourceAsset":{"type":"string"},"sourceNetwork":{"type":"string"},"destinationAsset":{"type":"string"},"destinationNetwork":{"type":"string"},"sourceAmount":{"type":"string","pattern":"^(?=.*[1-9])(?:0|[1-9]\\d*)(?:\\.\\d{1,18})?$","description":"Positive decimal string."},"rateType":{"enum":["best","fixed","floating"],"default":"best","description":"Use best for automatic selection. The returned quote states the applicable rate type."},"refundMode":{"enum":["sender","address"]},"refundAddress":{"type":"string"},"refundMemo":{"type":"string"}},"allOf":[{"if":{"properties":{"refundMode":{"const":"address"}},"required":["refundMode"]},"then":{"required":["refundAddress"]}}]},"Quote":{"type":"object","required":["id","sourceAmount","depositAmount","receiveAmount","rate","expiresAt","rateType"],"properties":{"id":{"type":"string","format":"uuid"},"sourceAmount":{"type":"string"},"depositAmount":{"type":"string"},"receiveAmount":{"type":"string"},"minimumReceiveAmount":{"type":["string","null"]},"feeUsd":{"type":["string","null"]},"rate":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"rateType":{"enum":["fixed","floating"]},"minimumSourceAmount":{"type":["string","null"]},"maximumSourceAmount":{"type":["string","null"]},"estimatedMinutes":{"type":["integer","null"]},"lateDepositPolicy":{"type":"string"}}},"SwapRequest":{"allOf":[{"$ref":"#/components/schemas/QuoteRequest"},{"type":"object","required":["quoteId","destinationAddress","rateType"],"properties":{"quoteId":{"type":"string"},"rateType":{"enum":["fixed","floating"]},"destinationAddress":{"type":"string"},"destinationMemo":{"type":"string"}}}]},"Swap":{"type":"object","required":["id","mode","sourceAsset","sourceNetwork","destinationAsset","destinationNetwork","destination","rateType","sourceAmount","status","terminal","actionRequired","retryable","reasonCode","termsVersion","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"mode":{"type":"string"},"sourceAsset":{"type":"string"},"sourceNetwork":{"type":"string"},"destinationAsset":{"type":"string"},"destinationNetwork":{"type":"string"},"destination":{"type":"string"},"destinationMemo":{"type":["string","null"]},"refundMode":{"enum":["sender","address"]},"refundAddress":{"type":["string","null"]},"refundMemo":{"type":["string","null"]},"rateType":{"enum":["floating","fixed"]},"sourceAmount":{"type":"string"},"expectedOutputAmount":{"type":["string","null"],"description":"Estimated receive amount."},"actualOutputAmount":{"type":["string","null"],"description":"Final received amount."},"minimumOutputAmount":{"type":["string","null"]},"depositAddress":{"type":["string","null"]},"depositMemo":{"type":["string","null"]},"sourceTxHash":{"type":["string","null"]},"settlementTxHash":{"type":["string","null"]},"refundTxHash":{"type":["string","null"]},"refundAmount":{"type":["string","null"]},"feeUsd":{"type":["string","null"]},"quoteExpiresAt":{"type":["string","null"],"format":"date-time"},"requiredConfirmations":{"type":["integer","null"]},"lateDepositPolicy":{"type":["string","null"]},"status":{"enum":["waiting","confirming","exchanging","sending","accumulating","finished","refunded","failed","expired","overdue","review"],"description":"Public swap status."},"terminal":{"type":"boolean","description":"True when this receipt will not transition again."},"actionRequired":{"enum":["none","customer","operator"]},"retryable":{"type":"boolean","description":"Whether repeating the same API action is safe and useful."},"reasonCode":{"enum":["payment_required","confirming","processing","accumulating","completed","refunded","support_required","manual_review"]},"failureCode":{"type":["string","null"]},"termsVersion":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"SwapEvent":{"type":"object","required":["id","orderId","status","terminal","actionRequired","retryable","reasonCode","occurredAt"],"properties":{"id":{"type":"string"},"orderId":{"type":"string"},"status":{"enum":["waiting","confirming","exchanging","sending","accumulating","finished","refunded","failed","expired","overdue","review"]},"terminal":{"type":"boolean"},"actionRequired":{"enum":["none","customer","operator"]},"retryable":{"type":"boolean"},"reasonCode":{"type":"string"},"confirmationCount":{"type":["integer","null"]},"requiredConfirmations":{"type":["integer","null"]},"sourceTxHash":{"type":["string","null"]},"settlementTxHash":{"type":["string","null"]},"refundTxHash":{"type":["string","null"]},"occurredAt":{"type":"string","format":"date-time"}}},"PermanentRouteTarget":{"type":"object","required":["destinationAsset","destinationNetwork","destinationAddress"],"properties":{"destinationAsset":{"enum":["fUSD","ZANO"]},"destinationNetwork":{"const":"ZANO"},"destinationAddress":{"type":"string"},"label":{"type":"string","maxLength":80}}},"PermanentRouteRequest":{"allOf":[{"$ref":"#/components/schemas/PermanentRouteTarget"},{"type":"object","required":["externalUserId","challengeId","message","publicKey","signature"],"description":"Submit the proof for the ownership challenge returned by POST /permanent-routes/challenges.","properties":{"externalUserId":{"type":"string","description":"Partner-controlled customer identifier."},"challengeId":{"type":"string","format":"uuid"},"message":{"type":"string"},"publicKey":{"type":"string"},"signature":{"type":"string"}}}]},"PermanentChallenge":{"type":"object","required":["challenge_id","challenge","expires_at"],"properties":{"challenge_id":{"type":"string","format":"uuid"},"challenge":{"type":"string","description":"Sign this exact challenge with the settlement wallet."},"expires_at":{"type":"string","format":"date-time"}}},"PermanentAddresses":{"type":"object","additionalProperties":{"type":"string"},"description":"Reusable deposit addresses keyed by asset and network. Use only non-empty entries."},"PermanentAccumulation":{"type":"object","required":["asset","network","accumulated_usd","threshold_usd","remaining_usd","same_asset_required","valued_at","message"],"properties":{"asset":{"type":"string"},"network":{"type":"string"},"accumulated_usd":{"type":"string","description":"Observed USD value waiting in this same-asset bucket."},"threshold_usd":{"type":"string","description":"Published processing threshold."},"remaining_usd":{"type":"string","description":"Additional observed USD value needed in this same asset."},"same_asset_required":{"const":true},"valued_at":{"type":"string","format":"date-time"},"message":{"type":"string"}}},"PermanentRoute":{"type":"object","required":["route_id","external_user_id","destination_asset","destination_network","destination_address","status","addresses","fee","min_swap_usd","accumulations","created_at","updated_at"],"properties":{"route_id":{"type":"string","format":"uuid"},"external_user_id":{"type":"string"},"destination_asset":{"enum":["fUSD","ZANO"]},"destination_network":{"const":"ZANO"},"destination_address":{"type":"string"},"label":{"type":"string"},"status":{"type":"string"},"addresses":{"$ref":"#/components/schemas/PermanentAddresses"},"fee":{"type":"object","required":["percent","floor_usd"],"properties":{"percent":{"type":"number"},"floor_usd":{"type":"number"}}},"min_swap_usd":{"type":"number"},"accumulations":{"type":"array","items":{"$ref":"#/components/schemas/PermanentAccumulation"}},"expect_deposit_until":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"PermanentRouteList":{"type":"object","required":["routes"],"properties":{"routes":{"type":"array","items":{"$ref":"#/components/schemas/PermanentRoute"}}}},"PermanentDeposit":{"type":"object","required":["id","asset","network","txHash","outputIndex","amountBaseUnits","confirmationCount","requiredConfirmations","status","terminal","actionRequired","retryable","reasonCode","accumulated_usd","threshold_usd","remaining_usd","same_asset_required","valued_at","message","firstSeenAt","lastSeenAt"],"properties":{"id":{"type":"string","format":"uuid"},"asset":{"type":"string"},"network":{"type":"string"},"txHash":{"type":"string"},"outputIndex":{"type":"integer"},"amountBaseUnits":{"type":"string"},"confirmationCount":{"type":"integer"},"requiredConfirmations":{"type":"integer"},"status":{"enum":["waiting","confirming","exchanging","sending","accumulating","finished","refunded","failed","expired","overdue","review"]},"terminal":{"type":"boolean"},"actionRequired":{"enum":["none","customer","operator"]},"retryable":{"type":"boolean"},"reasonCode":{"type":"string"},"orderId":{"type":["string","null"]},"settlementTxHash":{"type":["string","null"]},"actualOutputAmount":{"type":["string","null"]},"firstSeenAt":{"type":"string","format":"date-time"},"lastSeenAt":{"type":"string","format":"date-time"},"confirmedAt":{"type":["string","null"],"format":"date-time"},"accumulated_usd":{"type":["string","null"]},"threshold_usd":{"type":["string","null"]},"remaining_usd":{"type":["string","null"]},"same_asset_required":{"type":"boolean"},"valued_at":{"type":["string","null"],"format":"date-time"},"message":{"type":["string","null"]}}},"PermanentDepositList":{"type":"object","required":["route_id","accumulations","deposits"],"properties":{"route_id":{"type":"string","format":"uuid"},"accumulations":{"type":"array","items":{"$ref":"#/components/schemas/PermanentAccumulation"}},"deposits":{"type":"array","items":{"$ref":"#/components/schemas/PermanentDeposit"}}}},"PermanentDepositExpectation":{"type":"object","required":["ok","expect_deposit_until"],"properties":{"ok":{"const":true},"expect_deposit_until":{"type":"string","format":"date-time"}}}}}}