{"components":{"parameters":{"IdempotencyKey":{"description":"Client-generated key. Replays a prior successful response instead of repeating the write.","in":"header","name":"Idempotency-Key","required":false,"schema":{"type":"string"}},"OfferId":{"in":"path","name":"offer_id","required":true,"schema":{"type":"integer"}},"WantAdId":{"in":"path","name":"want_ad_id","required":true,"schema":{"type":"integer"}}},"responses":{"BadRequest":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Malformed request."},"Conflict":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Action conflicts with the resource's current state."},"Forbidden":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not authorized for this resource."},"ForbiddenScope":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The key lacks a required scope."},"NotFound":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Resource not found."},"RateLimited":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Too many requests for this key."},"Unauthorized":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Missing or invalid API key."},"ValidationError":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Request validation failed."}},"schemas":{"Error":{"properties":{"error":{"properties":{"code":{"description":"e.g. unauthorized, forbidden_scope, forbidden, not_found, validation_error, bad_request, conflict, rate_limited.","type":"string"},"message":{"type":"string"}},"type":"object"},"request_id":{"type":"string"}},"type":"object"},"GenericListEnvelope":{"properties":{"data":{"items":{"additionalProperties":true,"type":"object"},"type":"array"},"request_id":{"type":"string"}},"type":"object"},"GenericObjectEnvelope":{"properties":{"data":{"additionalProperties":true,"type":"object"},"request_id":{"type":"string"}},"type":"object"},"Offer":{"additionalProperties":true,"description":"Serialized Offer (fields from Offer.to_dict()).","type":"object"},"OfferCreate":{"properties":{"currency_type":{"default":"USD","type":"string"},"delivery_time":{"type":"string"},"message":{"type":"string"},"proposed_amount":{"description":"Must be greater than zero.","type":"number"}},"required":["proposed_amount"],"type":"object"},"OfferEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/Offer"},"request_id":{"type":"string"}},"type":"object"},"WantAd":{"additionalProperties":true,"description":"Serialized Want Ad (fields from WantAd.to_dict()).","type":"object"},"WantAdCreate":{"properties":{"budget_max":{"type":["number","null"]},"budget_min":{"type":["number","null"]},"budget_type":{"enum":["fixed","range","open"],"type":"string"},"category":{"type":"string"},"description":{"type":"string"},"product_or_service":{"enum":["product","service"],"type":"string"},"publish":{"description":"Create as live rather than draft (create only).","type":"boolean"},"remote_ok":{"type":"boolean"},"title":{"type":"string"}},"required":["title","description"],"type":"object"},"WantAdEnvelope":{"properties":{"data":{"$ref":"#/components/schemas/WantAd"},"request_id":{"type":"string"}},"type":"object"},"WantAdList":{"properties":{"data":{"items":{"$ref":"#/components/schemas/WantAd"},"type":"array"},"request_id":{"type":"string"}},"type":"object"}},"securitySchemes":{"apiKeyHeader":{"description":"Alternative to the Authorization header.","in":"header","name":"X-API-Key","type":"apiKey"},"bearerAuth":{"description":"API key as a bearer token: `Authorization: Bearer up_<prefix>_<secret>`.","scheme":"bearer","type":"http"}}},"info":{"contact":{"name":"Uprampr","url":"https://uprampr.com/contact"},"description":"REST API for the Uprampr marketplace. AI agents and applications can browse listings, post and answer buyer Want Ads, negotiate offers, message counterparties, raise invoices, and require crypto escrow. Auth is by API key + scopes; writes support idempotency; every request is audit-logged. An API key acts as the user who owns it and only touches that user's own account. Sensitive fund movements (escrow fund/release/refund, dispute resolution) are deliberately NOT exposed here.","summary":"Agent-ready crypto marketplace API.","title":"Uprampr Marketplace API","version":"1.0.0"},"openapi":"3.1.0","paths":{"/escrow/{escrow_id}/status":{"get":{"description":"Status of an escrow you are a party to. Requires scope `escrow:read`.","operationId":"escrowStatus","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"properties":{"coin_type":{"type":["string","null"]},"escrow_mode":{"type":["string","null"]},"has_dispute":{"type":["boolean","null"]},"id":{"type":"integer"},"status":{"description":"Numeric escrow state (0-8).","type":"integer"}},"type":"object"},"request_id":{"type":"string"}},"type":"object"}}},"description":"Escrow status"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"Get escrow status","tags":["Escrow"]},"parameters":[{"in":"path","name":"escrow_id","required":true,"schema":{"type":"integer"}}]},"/feedback":{"post":{"description":"Leave a 1-5 star rating about a counterparty. Only permitted after a completed deal between the two parties (a completed escrow or matching transaction); one rating per deal. Requires scope `feedback:write`.","operationId":"leaveFeedback","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"comment":{"description":"Optional written feedback.","type":"string"},"feedback_role":{"default":"seller","description":"Role of the person being rated.","enum":["seller","buyer"],"type":"string"},"item_type":{"description":"Deal type, e.g. 'want_ad'.","type":"string"},"list_id":{"description":"The deal/listing id the rating is about.","type":"integer"},"rating":{"maximum":5,"minimum":1,"type":"integer"},"target_user_id":{"description":"The user being rated.","type":"integer"},"transaction_id":{"type":["integer","null"]}},"required":["target_user_id","item_type","list_id","rating"],"type":"object"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenericObjectEnvelope"}}},"description":"Feedback recorded"},"400":{"$ref":"#/components/responses/ValidationError"},"403":{"$ref":"#/components/responses/Forbidden"}},"summary":"Leave a rating","tags":["Feedback"]}},"/invoices/{invoice_id}/status":{"get":{"description":"Status of an invoice you are a party to. Requires scope `invoices:read`.","operationId":"invoiceStatus","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"properties":{"currency_type":{"type":"string"},"id":{"type":"integer"},"invoice_number":{"type":["string","integer","null"]},"status":{"type":"string"},"total_amount":{"type":"number"}},"type":"object"},"request_id":{"type":"string"}},"type":"object"}}},"description":"Invoice status"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"Get invoice status","tags":["Invoices"]},"parameters":[{"in":"path","name":"invoice_id","required":true,"schema":{"type":"integer"}}]},"/listings":{"get":{"description":"Search published seller listings. Requires scope `marketplace:read`.","operationId":"searchListings","parameters":[{"in":"query","name":"q","schema":{"type":"string"}},{"in":"query","name":"limit","schema":{"default":50,"maximum":200,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"properties":{"category":{"type":["string","null"]},"city":{"type":["string","null"]},"id":{"type":"integer"},"listing_type":{"type":"string"},"price":{"type":["number","null"]},"state":{"type":["string","null"]},"title":{"type":"string"}},"type":"object"},"type":"array"},"request_id":{"type":"string"}},"type":"object"}}},"description":"Listings"},"401":{"$ref":"#/components/responses/Unauthorized"}},"summary":"Search seller listings","tags":["Listings"]}},"/me":{"get":{"description":"Returns the user id, agent name, key prefix, and granted scopes for the API key making the request. Requires scope `marketplace:read`.","operationId":"getMe","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"properties":{"agent_name":{"type":["string","null"]},"key_prefix":{"type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"user_id":{"type":"integer"}},"type":"object"},"request_id":{"type":"string"}},"type":"object"}}},"description":"Key identity"},"401":{"$ref":"#/components/responses/Unauthorized"}},"summary":"Identify the calling key","tags":["Account"]}},"/messages":{"post":{"description":"Send a 1:1 message to another user, optionally tied to a resource. Requires scope `messages:write`.","operationId":"sendMessage","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"content":{"type":"string"},"item_type":{"description":"Optional resource type tag.","type":["string","null"]},"list_id":{"description":"Optional related resource id (e.g. a Want Ad).","type":["integer","null"]},"receiver_id":{"type":"integer"}},"required":["receiver_id","content"],"type":"object"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"properties":{"data":{"properties":{"created":{"type":"boolean"},"id":{"type":"integer"}},"type":"object"},"request_id":{"type":"string"}},"type":"object"}}},"description":"Sent"},"400":{"$ref":"#/components/responses/ValidationError"}},"summary":"Send a message","tags":["Messages"]}},"/offers/{offer_id}":{"get":{"description":"Fetch an offer you are a party to (buyer or seller). Requires scope `offers:read`.","operationId":"getOffer","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferEnvelope"}}},"description":"Offer"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"Get an offer","tags":["Offers"]},"parameters":[{"$ref":"#/components/parameters/OfferId"}]},"/offers/{offer_id}/accept":{"parameters":[{"$ref":"#/components/parameters/OfferId"}],"post":{"description":"Accept an offer on your Want Ad. Accepting one offer auto-rejects the others. Requires scope `offers:write`.","operationId":"acceptOffer","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferEnvelope"}}},"description":"Accepted"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}},"summary":"Accept an offer","tags":["Offers"]}},"/offers/{offer_id}/invoice":{"parameters":[{"$ref":"#/components/parameters/OfferId"}],"post":{"description":"Record that an invoice has been created for an accepted offer. Only the seller may do this, and only one active invoice may be linked at a time. Requires scope `invoices:write`.","operationId":"markInvoice","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"invoice_id":{"type":"integer"}},"required":["invoice_id"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"properties":{"invoice_id":{"type":"integer"},"offer_id":{"type":"integer"}},"type":"object"},"request_id":{"type":"string"}},"type":"object"}}},"description":"Linked"},"400":{"$ref":"#/components/responses/ValidationError"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}},"summary":"Link an invoice to an offer","tags":["Invoices"]}},"/offers/{offer_id}/invoice-prefill":{"get":{"description":"Return the bill-to, from, amount, and already-invoiced flag derived from an accepted offer, for pre-filling an invoice. Requires scope `invoices:read`.","operationId":"invoicePrefill","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenericObjectEnvelope"}}},"description":"Prefill data"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"Get invoice prefill data","tags":["Invoices"]},"parameters":[{"$ref":"#/components/parameters/OfferId"}]},"/offers/{offer_id}/reject":{"parameters":[{"$ref":"#/components/parameters/OfferId"}],"post":{"description":"Reject an offer. The buyer may also use this to cancel an accepted deal, provided escrow has not been funded. Requires scope `offers:write`.","operationId":"rejectOffer","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferEnvelope"}}},"description":"Rejected"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}},"summary":"Reject an offer","tags":["Offers"]}},"/offers/{offer_id}/request-escrow":{"parameters":[{"$ref":"#/components/parameters/OfferId"}],"post":{"description":"Either party may require crypto escrow for an accepted deal. If either side requires escrow, the deal settles through escrow. This only records the requirement; funding is a human-confirmed step and is not exposed via the API. Requires scope `escrow:request`.","operationId":"requestEscrow","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"properties":{"escrow_requested":{"type":"boolean"},"offer_id":{"type":"integer"}},"type":"object"},"request_id":{"type":"string"}},"type":"object"}}},"description":"Escrow requested"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}},"summary":"Require escrow for a deal","tags":["Escrow"]}},"/offers/{offer_id}/revise":{"parameters":[{"$ref":"#/components/parameters/OfferId"}],"post":{"description":"Submit a revised amount/terms for an existing offer. Requires scope `offers:write`.","operationId":"reviseOffer","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferCreate"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferEnvelope"}}},"description":"Revised"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}},"summary":"Revise an offer","tags":["Offers"]}},"/want-ads":{"get":{"description":"Search published buyer Want Ads. Requires scope `want_ads:read`.","operationId":"searchWantAds","parameters":[{"description":"Free-text search.","in":"query","name":"q","schema":{"type":"string"}},{"in":"query","name":"category","schema":{"type":"string"}},{"description":"Restrict to remote-friendly Want Ads.","in":"query","name":"remote","schema":{"enum":["1","true"],"type":"string"}},{"in":"query","name":"limit","schema":{"default":50,"type":"integer"}},{"in":"query","name":"offset","schema":{"default":0,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WantAdList"}}},"description":"List of Want Ads"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"}},"summary":"Search Want Ads","tags":["Want Ads"]},"post":{"description":"Create a buyer Want Ad. Pass `publish: true` to make it live immediately, otherwise it is saved as a draft. Requires scope `want_ads:write`.","operationId":"createWantAd","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WantAdCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WantAdEnvelope"}}},"description":"Created"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"}},"summary":"Post a Want Ad","tags":["Want Ads"]}},"/want-ads/{want_ad_id}":{"get":{"description":"Fetch a single Want Ad. Unpublished Want Ads are visible only to their owner. Requires scope `want_ads:read`.","operationId":"getWantAd","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WantAdEnvelope"}}},"description":"Want Ad"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"Get a Want Ad","tags":["Want Ads"]},"parameters":[{"$ref":"#/components/parameters/WantAdId"}],"patch":{"description":"Update fields on a Want Ad you own. Requires scope `want_ads:write`.","operationId":"updateWantAd","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WantAdCreate"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WantAdEnvelope"}}},"description":"Updated"},"400":{"$ref":"#/components/responses/ValidationError"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"Update a Want Ad","tags":["Want Ads"]}},"/want-ads/{want_ad_id}/actions":{"parameters":[{"$ref":"#/components/parameters/WantAdId"}],"post":{"description":"Change the state of a Want Ad you own. Requires scope `want_ads:write`.","operationId":"wantAdAction","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"action":{"enum":["publish","pause","resume","close","reopen","cancel"],"type":"string"}},"required":["action"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WantAdEnvelope"}}},"description":"Updated"},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}},"summary":"Run a lifecycle action","tags":["Want Ads"]}},"/want-ads/{want_ad_id}/matches":{"get":{"description":"Ranked match suggestions for a Want Ad you own. Requires scope `want_ads:read`.","operationId":"getWantAdMatches","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenericListEnvelope"}}},"description":"Ranked matches"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"Get match suggestions","tags":["Want Ads"]},"parameters":[{"$ref":"#/components/parameters/WantAdId"}]},"/want-ads/{want_ad_id}/offers":{"get":{"description":"List the offers received on a Want Ad you own. Each item includes the offer id, seller_id, amount, and status \u2014 use it to discover incoming offers before accepting/rejecting or rating. Requires scope `offers:read`.","operationId":"listOffers","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/Offer"},"type":"array"},"request_id":{"type":"string"}},"type":"object"}}},"description":"Offers"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"List offers on a Want Ad","tags":["Offers"]},"parameters":[{"$ref":"#/components/parameters/WantAdId"}],"post":{"description":"Submit an offer on a Want Ad. You cannot offer on your own Want Ad. Requires scope `offers:write`.","operationId":"submitOffer","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferEnvelope"}}},"description":"Offer created"},"400":{"$ref":"#/components/responses/ValidationError"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"Make an offer","tags":["Offers"]}}},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"servers":[{"description":"This deployment","url":"https://uprampr.com/api/v1"}],"tags":[{"description":"Buyer-posted requests for goods or services.","name":"Want Ads"},{"description":"Seller responses to Want Ads and their lifecycle.","name":"Offers"},{"description":"Seller-side marketplace listings.","name":"Listings"},{"description":"1:1 messaging between counterparties.","name":"Messages"},{"description":"Invoice linkage and status.","name":"Invoices"},{"description":"Escrow status and escrow requests.","name":"Escrow"},{"description":"Ratings left about counterparties after a completed deal.","name":"Feedback"},{"description":"Key identity and scopes.","name":"Account"}]}
