{"id":8985,"date":"2024-08-30T16:46:10","date_gmt":"2024-08-30T11:16:10","guid":{"rendered":"https:\/\/www.satup.xyz\/index.php\/2024\/08\/30\/strategies-best-practices-every-firefly-services-api-developer-should-know-by-kelvin-xu-aug-2024\/"},"modified":"2024-08-30T16:46:10","modified_gmt":"2024-08-30T11:16:10","slug":"strategies-best-practices-every-firefly-services-api-developer-should-know-by-kelvin-xu-aug-2024","status":"publish","type":"post","link":"https:\/\/www.satup.xyz\/index.php\/2024\/08\/30\/strategies-best-practices-every-firefly-services-api-developer-should-know-by-kelvin-xu-aug-2024\/","title":{"rendered":"Strategies &#038; Best Practices Every Firefly Services API Developer Should Know | by Kelvin Xu | Aug, 2024"},"content":{"rendered":"<p><br \/>\n<\/p>\n<div>\n<div>\n<div>\n<div class=\"speechify-ignore ab cp\">\n<div class=\"speechify-ignore bh l\">\n<div class=\"hv hw hx hy hz ab\">\n<div>\n<div class=\"ab ia\"><a href=\"https:\/\/medium.com\/@kelvinxu88?source=post_page-----42d8b74a226d--------------------------------\" rel=\"noopener follow\"><\/p>\n<div>\n<div class=\"bm\" aria-hidden=\"false\">\n<div class=\"l ib ic by id ie\">\n<div class=\"l fj\"><img loading=\"lazy\" decoding=\"async\" alt=\"Kelvin Xu\" class=\"l fd by dd de cx\" src=\"https:\/\/miro.medium.com\/v2\/resize:fill:88:88\/1*s4dWwy9-DZ7iShHUtJ9WjQ.jpeg\" width=\"44\" height=\"44\" loading=\"lazy\" data-testid=\"authorPhoto\"\/><\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><\/a><a href=\"https:\/\/blog.developer.adobe.com\/?source=post_page-----42d8b74a226d--------------------------------\" rel=\"noopener  ugc nofollow\"><\/p>\n<div class=\"ih ab fj\">\n<div>\n<div class=\"bm\" aria-hidden=\"false\">\n<div class=\"l ii ij by id ik\">\n<div class=\"l fj\"><img loading=\"lazy\" decoding=\"async\" alt=\"Adobe Tech Blog\" class=\"l fd by br il cx\" src=\"https:\/\/miro.medium.com\/v2\/resize:fill:48:48\/1*riyFijvwTfGcWNf1guRNtg.png\" width=\"24\" height=\"24\" loading=\"lazy\" data-testid=\"publicationPhoto\"\/><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><\/a><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<figure class=\"mz na nb nc nd ne mw mx paragraph-image\">\n<div role=\"button\" tabindex=\"0\" class=\"nf ng fj nh bh ni\">\n<div class=\"mw mx my\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*NngEnPJDqTxjnv4jxIsouA.jpeg 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*NngEnPJDqTxjnv4jxIsouA.jpeg 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*NngEnPJDqTxjnv4jxIsouA.jpeg 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*NngEnPJDqTxjnv4jxIsouA.jpeg 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*NngEnPJDqTxjnv4jxIsouA.jpeg 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*NngEnPJDqTxjnv4jxIsouA.jpeg 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/format:webp\/1*NngEnPJDqTxjnv4jxIsouA.jpeg 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" type=\"image\/webp\"\/><source data-testid=\"og\" srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*NngEnPJDqTxjnv4jxIsouA.jpeg 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*NngEnPJDqTxjnv4jxIsouA.jpeg 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*NngEnPJDqTxjnv4jxIsouA.jpeg 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*NngEnPJDqTxjnv4jxIsouA.jpeg 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*NngEnPJDqTxjnv4jxIsouA.jpeg 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*NngEnPJDqTxjnv4jxIsouA.jpeg 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*NngEnPJDqTxjnv4jxIsouA.jpeg 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\"\/><img fetchpriority=\"high\" alt=\"\" class=\"bh md nj c\" width=\"700\" height=\"380\" loading=\"eager\" role=\"presentation\"\/><\/picture><\/div>\n<\/div>\n<\/figure>\n<p id=\"8204\" class=\"pw-post-body-paragraph nk nl gu nm b nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe of og oh gn bk\">Adobe <a class=\"af oi\" href=\"https:\/\/developer.adobe.com\/firefly-services\/docs\/guides\/\" rel=\"noopener ugc nofollow\" target=\"_blank\">Firefly Services<\/a> offers a comprehensive set of generative AI and creative APIs that can enhance enterprise processes and workflows. The services include APIs such as Firefly APIs, Photoshop APIs, Lightroom APIs, and Content Tagging APIs. These APIs, having evolved from different backgrounds and timelines, exhibit some differences in API signatures, input\/output formats, and response behaviors. It\u2019s crucial to understand these nuances and adopt key strategies and best practices that can guide developers in using these APIs effectively.<\/p>\n<p id=\"6f67\" class=\"pw-post-body-paragraph nk nl gu nm b nn ph np nq nr pi nt nu nv pj nx ny nz pk ob oc od pl of og oh gn bk\">Authentication is the foremost step before making any valid API request. Licensed customers can follow the guide <a class=\"af oi\" href=\"https:\/\/developer.adobe.com\/firefly-services\/docs\/guides\/get-started\/\" rel=\"noopener ugc nofollow\" target=\"_blank\">here<\/a> to obtain the client ID and client secret, then use a curl command to acquire the access token. This process is fairly straightforward, but it\u2019s important to note that this is a <a class=\"af oi\" href=\"https:\/\/developer.adobe.com\/developer-console\/docs\/guides\/authentication\/ServerToServerAuthentication\/\" rel=\"noopener ugc nofollow\" target=\"_blank\">server-to-server authentication<\/a> mechanism, meaning that it does not involve your application\u2019s end users logging in. The authentication occurs solely between your application and Firefly Services, so it\u2019s essential to implement it securely.<\/p>\n<p id=\"ea67\" class=\"pw-post-body-paragraph nk nl gu nm b nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe of og oh gn bk\">For example, in web application development, developers must avoid obtaining the access token from the client side, as this could easily expose credentials. The access token should be fetched on the server side to ensure that credentials remain secure.<\/p>\n<p id=\"058a\" class=\"pw-post-body-paragraph nk nl gu nm b nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe of og oh gn bk\">When implementing this in practice, consider using a common library or method to generate the token centrally. If you\u2019re using Node.js, you can leverage <a class=\"af oi\" href=\"https:\/\/github.com\/adobe\/aio-lib-ims\" rel=\"noopener ugc nofollow\" target=\"_blank\">this library<\/a>. Since the token is valid for 24 hours, it\u2019s wise to cache it (e.g. with a TTL of 23 hours and 55 minutes) and reuse it rather than fetching a new token every time.<\/p>\n<p id=\"2508\" class=\"pw-post-body-paragraph nk nl gu nm b nn ph np nq nr pi nt nu nv pj nx ny nz pk ob oc od pl of og oh gn bk\">Both Photoshop (including Lightroom) and Firefly APIs generally require <a class=\"af oi\" href=\"https:\/\/developer.adobe.com\/firefly-services\/docs\/photoshop\/general-workflow\/#input-and-output-file-storage\" rel=\"noopener ugc nofollow\" target=\"_blank\">input and output images<\/a> to be served from cloud storage or pre-signed URLs. These APIs currently support S3, Azure Blob Storage, and Dropbox. For Photoshop APIs, a resource served from a pre-signed URL is required to start any API operation. Firefly, however, provides an <a class=\"af oi\" href=\"https:\/\/developer.adobe.com\/firefly-services\/docs\/firefly-api\/guides\/api\/upload_image\/\" rel=\"noopener ugc nofollow\" target=\"_blank\">upload endpoint<\/a> for temporarily storing source files if no cloud storage is available. This upload endpoint returns an upload ID rather than a pre-signed URL, which means it cannot be reused in Photoshop (and Lightroom) APIs. Therefore, if your implementation involves orchestration across Firefly and Photoshop APIs, it\u2019s advisable to have cloud storage ready from the start.<\/p>\n<p id=\"c72a\" class=\"pw-post-body-paragraph nk nl gu nm b nn ph np nq nr pi nt nu nv pj nx ny nz pk ob oc od pl of og oh gn bk\">As of now, Firefly APIs are synchronous, meaning that after making a request, you will receive the results (either success with output images or failure with an error message) in the response within a few seconds. This real-time generation does require some computational time.<\/p>\n<figure class=\"pn po pp pq pr ne mw mx paragraph-image\">\n<div class=\"mw mx pm\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*cRwJSKB18L44658arbmK8g.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*cRwJSKB18L44658arbmK8g.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*cRwJSKB18L44658arbmK8g.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*cRwJSKB18L44658arbmK8g.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*cRwJSKB18L44658arbmK8g.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*cRwJSKB18L44658arbmK8g.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:990\/format:webp\/1*cRwJSKB18L44658arbmK8g.png 990w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 495px\" type=\"image\/webp\"\/><source data-testid=\"og\" srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*cRwJSKB18L44658arbmK8g.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*cRwJSKB18L44658arbmK8g.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*cRwJSKB18L44658arbmK8g.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*cRwJSKB18L44658arbmK8g.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*cRwJSKB18L44658arbmK8g.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*cRwJSKB18L44658arbmK8g.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:990\/1*cRwJSKB18L44658arbmK8g.png 990w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 495px\"\/><img loading=\"lazy\" alt=\"\" class=\"bh md nj c\" width=\"495\" height=\"117\" loading=\"lazy\" role=\"presentation\"\/><\/picture><\/div>\n<\/figure>\n<p id=\"217d\" class=\"pw-post-body-paragraph nk nl gu nm b nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe of og oh gn bk\">On the other hand, Photoshop APIs are asynchronous. After making a request, you will immediately receive a job ID rather than the actual outputs. You will then need to <a class=\"af oi\" href=\"https:\/\/developer.adobe.com\/firefly-services\/docs\/photoshop\/code-sample\/#fetch-the-status-of-an-api\" rel=\"noopener ugc nofollow\" target=\"_blank\">poll the job status<\/a> using the job ID until you receive the results.<\/p>\n<figure class=\"pn po pp pq pr ne mw mx paragraph-image\">\n<div class=\"mw mx ps\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*yD0fVLFOENK1LQXOj4ckVg.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*yD0fVLFOENK1LQXOj4ckVg.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*yD0fVLFOENK1LQXOj4ckVg.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*yD0fVLFOENK1LQXOj4ckVg.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*yD0fVLFOENK1LQXOj4ckVg.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*yD0fVLFOENK1LQXOj4ckVg.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:986\/format:webp\/1*yD0fVLFOENK1LQXOj4ckVg.png 986w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 493px\" type=\"image\/webp\"\/><source data-testid=\"og\" srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*yD0fVLFOENK1LQXOj4ckVg.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*yD0fVLFOENK1LQXOj4ckVg.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*yD0fVLFOENK1LQXOj4ckVg.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*yD0fVLFOENK1LQXOj4ckVg.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*yD0fVLFOENK1LQXOj4ckVg.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*yD0fVLFOENK1LQXOj4ckVg.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:986\/1*yD0fVLFOENK1LQXOj4ckVg.png 986w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 493px\"\/><img loading=\"lazy\" alt=\"\" class=\"bh md nj c\" width=\"493\" height=\"118\" loading=\"lazy\" role=\"presentation\"\/><\/picture><\/div>\n<\/figure>\n<p id=\"e3b4\" class=\"pw-post-body-paragraph nk nl gu nm b nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe of og oh gn bk\">Understanding these API characteristics will help you design and develop your applications more effectively (Ideally, both APIs should support both synchronous and asynchronous operations, or at least offer a choice).<\/p>\n<p id=\"65dc\" class=\"pw-post-body-paragraph nk nl gu nm b nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe of og oh gn bk\">For real-time generation apps using Firefly APIs, you may need to set up appropriate expectations upfront, perhaps by using a loading spinner or skeleton loader on the UI side. For Photoshop APIs, asynchronous processing is excellent for parallel processing at scale. However, for real-time user interactions, you might need to \u201cconvert\u201d the asynchronous behavior to synchronous by introducing status polling until completion, or by using the <a class=\"af oi\" href=\"https:\/\/github.com\/Firefly-Services\/firefly-services-sdk-js\/blob\/main\/examples\/javascript\/photoshop\/photoshop.js#L70\" rel=\"noopener ugc nofollow\" target=\"_blank\">Firefly SDK<\/a>, which encapsulates the polling process for you.<\/p>\n<p id=\"378c\" class=\"pw-post-body-paragraph nk nl gu nm b nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe of og oh gn bk\">For scalable parallel processing, you also can leverage eventing. Photoshop supports eventing through Adobe\u2019s serverless platform, <a class=\"af oi\" href=\"https:\/\/developer.adobe.com\/firefly-services\/docs\/photoshop\/features\/#webhooks-through-adobe-io-events\" rel=\"noopener ugc nofollow\" target=\"_blank\">Adobe IO Events<\/a>.<\/p>\n<figure class=\"pn po pp pq pr ne mw mx paragraph-image\">\n<div class=\"mw mx pt\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*6PsRqNoDAnjqp7vuVDindw.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*6PsRqNoDAnjqp7vuVDindw.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*6PsRqNoDAnjqp7vuVDindw.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*6PsRqNoDAnjqp7vuVDindw.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*6PsRqNoDAnjqp7vuVDindw.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*6PsRqNoDAnjqp7vuVDindw.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1120\/format:webp\/1*6PsRqNoDAnjqp7vuVDindw.png 1120w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 560px\" type=\"image\/webp\"\/><source data-testid=\"og\" srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*6PsRqNoDAnjqp7vuVDindw.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*6PsRqNoDAnjqp7vuVDindw.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*6PsRqNoDAnjqp7vuVDindw.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*6PsRqNoDAnjqp7vuVDindw.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*6PsRqNoDAnjqp7vuVDindw.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*6PsRqNoDAnjqp7vuVDindw.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1120\/1*6PsRqNoDAnjqp7vuVDindw.png 1120w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 560px\"\/><img loading=\"lazy\" alt=\"\" class=\"bh md nj c\" width=\"560\" height=\"317\" loading=\"lazy\" role=\"presentation\"\/><\/picture><\/div>\n<\/figure>\n<p id=\"28f4\" class=\"pw-post-body-paragraph nk nl gu nm b nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe of og oh gn bk\">In this model, the client doesn\u2019t need to poll the status continuously, as a job completion event will be emitted to IO Events, to which a webhook or IO runtime action can subscribe. This approach allows the client to be more performant and is ideal for implementing bulk processing (the webhook or IO runtime action running in Adobe IO platform is <a class=\"af oi\" rel=\"noopener ugc nofollow\" target=\"_blank\" href=\"https:\/\/blog.developer.adobe.com\/adobe-app-builder-the-power-of-scaling-at-your-fingertips-8ae1149b7ebd\">autoscaled<\/a>).<\/p>\n<p id=\"5d84\" class=\"pw-post-body-paragraph nk nl gu nm b nn ph np nq nr pi nt nu nv pj nx ny nz pk ob oc od pl of og oh gn bk\">By default, Firefly APIs have a <a class=\"af oi\" href=\"https:\/\/developer.adobe.com\/firefly-services\/docs\/firefly-api\/guides\/concepts\/rate-limits\/\" rel=\"noopener ugc nofollow\" target=\"_blank\">rate limit<\/a> of 4 RPM (requests per minute) and 9,000 RPD (requests per day). Licensed customers can request higher limits based on their annual quota and estimated traffic. However, despite the best estimations, hitting the rate limit might be inevitable during unexpected traffic spikes, or a large campaign event.<\/p>\n<p id=\"9ac0\" class=\"pw-post-body-paragraph nk nl gu nm b nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe of og oh gn bk\">A common strategy is to implement a retry logic. If you encounter a 429 response code, you can retry after waiting for the \u201cretry-after\u201d period indicated in the response header or implement an <a class=\"af oi\" href=\"https:\/\/docs.aws.amazon.com\/prescriptive-guidance\/latest\/cloud-design-patterns\/retry-backoff.html\" rel=\"noopener ugc nofollow\" target=\"_blank\">exponential backoff pattern<\/a>.<\/p>\n<figure class=\"pn po pp pq pr ne mw mx paragraph-image\">\n<div class=\"mw mx pu\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*-aJuvu-0rE2S-kHoq7RrhQ.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*-aJuvu-0rE2S-kHoq7RrhQ.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*-aJuvu-0rE2S-kHoq7RrhQ.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*-aJuvu-0rE2S-kHoq7RrhQ.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*-aJuvu-0rE2S-kHoq7RrhQ.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*-aJuvu-0rE2S-kHoq7RrhQ.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1034\/format:webp\/1*-aJuvu-0rE2S-kHoq7RrhQ.png 1034w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 517px\" type=\"image\/webp\"\/><source data-testid=\"og\" srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*-aJuvu-0rE2S-kHoq7RrhQ.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*-aJuvu-0rE2S-kHoq7RrhQ.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*-aJuvu-0rE2S-kHoq7RrhQ.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*-aJuvu-0rE2S-kHoq7RrhQ.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*-aJuvu-0rE2S-kHoq7RrhQ.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*-aJuvu-0rE2S-kHoq7RrhQ.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1034\/1*-aJuvu-0rE2S-kHoq7RrhQ.png 1034w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 517px\"\/><img loading=\"lazy\" alt=\"\" class=\"bh md nj c\" width=\"517\" height=\"141\" loading=\"lazy\" role=\"presentation\"\/><\/picture><\/div>\n<\/figure>\n<p id=\"0df8\" class=\"pw-post-body-paragraph nk nl gu nm b nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe of og oh gn bk\">Another strategy to avoid hitting the rate limit is pre-generation (in the case of text2image). The enterprises wanting to enforce brand consistency in generated images should also consider this strategy. The process can be split into pre-generation and delivery phases.<\/p>\n<figure class=\"pn po pp pq pr ne mw mx paragraph-image\">\n<div role=\"button\" tabindex=\"0\" class=\"nf ng fj nh bh ni\">\n<div class=\"mw mx pv\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*m5io5aWZy6W5SkL3PDsVXw.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*m5io5aWZy6W5SkL3PDsVXw.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*m5io5aWZy6W5SkL3PDsVXw.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*m5io5aWZy6W5SkL3PDsVXw.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*m5io5aWZy6W5SkL3PDsVXw.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*m5io5aWZy6W5SkL3PDsVXw.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/format:webp\/1*m5io5aWZy6W5SkL3PDsVXw.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" type=\"image\/webp\"\/><source data-testid=\"og\" srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*m5io5aWZy6W5SkL3PDsVXw.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*m5io5aWZy6W5SkL3PDsVXw.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*m5io5aWZy6W5SkL3PDsVXw.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*m5io5aWZy6W5SkL3PDsVXw.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*m5io5aWZy6W5SkL3PDsVXw.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*m5io5aWZy6W5SkL3PDsVXw.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*m5io5aWZy6W5SkL3PDsVXw.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\"\/><img loading=\"lazy\" alt=\"\" class=\"bh md nj c\" width=\"700\" height=\"180\" loading=\"lazy\" role=\"presentation\"\/><\/picture><\/div>\n<\/div>\n<\/figure>\n<p id=\"915c\" class=\"pw-post-body-paragraph nk nl gu nm b nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe of og oh gn bk\">During the pre-generation phase, enterprises can use predefined prompt templates to generate large number of images that maintain brand consistency (techniques including style\/structure referencing or customer models, etc.). This can be done over an extended period, respecting the rate limit, and storing the generated images in a database or cloud storage with search and query capabilities. Metadata and tagging can also be generated (i.e. using <a class=\"af oi\" href=\"https:\/\/experienceleague.adobe.com\/en\/docs\/experience-platform\/intelligent-services\/content-commerce-ai\/overview\" rel=\"noopener ugc nofollow\" target=\"_blank\">Content Tagging API<\/a> or GPT Vision) to assist in indexing.<\/p>\n<p id=\"2975\" class=\"pw-post-body-paragraph nk nl gu nm b nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe of og oh gn bk\">On the delivery side, client apps can guide users to turn their inputs into image queries against the stored images. These pre-generated images can be delivered directly or used to generate more personalized experiences based on user inputs. Since the images are pre-generated, quality and brand consistency can be ensured, real-time inference is avoided (cost effective), and hitting the rate limit is mitigated.<\/p>\n<\/div>\n<p><br \/>\n<br \/><a href=\"https:\/\/blog.developer.adobe.com\/firefly-services-api-strategies-best-practices-every-developer-should-know-42d8b74a226d?source=rss----9342990108af---4\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Adobe Firefly Services offers a comprehensive set of generative AI and creative APIs that can enhance enterprise processes and workflows. The services include APIs such as Firefly APIs, Photoshop APIs, Lightroom APIs, and Content Tagging APIs. These APIs, having evolved from different backgrounds and timelines, exhibit some differences in API signatures, input\/output formats, and response [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":8986,"comment_status":"","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[19],"tags":[],"class_list":["post-8985","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-graphics-design"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.satup.xyz\/index.php\/wp-json\/wp\/v2\/posts\/8985","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.satup.xyz\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.satup.xyz\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.satup.xyz\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.satup.xyz\/index.php\/wp-json\/wp\/v2\/comments?post=8985"}],"version-history":[{"count":0,"href":"https:\/\/www.satup.xyz\/index.php\/wp-json\/wp\/v2\/posts\/8985\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.satup.xyz\/index.php\/wp-json\/wp\/v2\/media\/8986"}],"wp:attachment":[{"href":"https:\/\/www.satup.xyz\/index.php\/wp-json\/wp\/v2\/media?parent=8985"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.satup.xyz\/index.php\/wp-json\/wp\/v2\/categories?post=8985"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.satup.xyz\/index.php\/wp-json\/wp\/v2\/tags?post=8985"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}