<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pablo Martinez</title>
    <description>The latest articles on DEV Community by Pablo Martinez (@pablotheblink).</description>
    <link>https://dev.to/pablotheblink</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4218831%2Fea71c5fd-6508-4987-ac50-065a4250e25e.jpg</url>
      <title>DEV Community: Pablo Martinez</title>
      <link>https://dev.to/pablotheblink</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pablotheblink"/>
    <language>en</language>
    <item>
      <title>Simplificando la extracción de datos de licitaciones europeas (TED): Un enfoque práctico</title>
      <dc:creator>Pablo Martinez</dc:creator>
      <pubDate>Sat, 31 Oct 2026 21:17:40 +0000</pubDate>
      <link>https://dev.to/pablotheblink/simplificando-la-extraccion-de-datos-de-licitaciones-europeas-ted-un-enfoque-practico-563f</link>
      <guid>https://dev.to/pablotheblink/simplificando-la-extraccion-de-datos-de-licitaciones-europeas-ted-un-enfoque-practico-563f</guid>
      <description>&lt;p&gt;Trabajar con datos de contratación pública europea a través de la plataforma TED (Tenders Electronic Daily) es fundamental para muchos proyectos cívicos y empresariales. Sin embargo, quienes han lidiado con la API oficial o los volcados masivos de datos saben que la curva de aprendizaje puede ser empinada. La complejidad de los esquemas XML/JSON y la estructura de las consultas a menudo ralentizan la fase de desarrollo y prototipado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;El desafío habitual&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Supongamos un escenario común: necesitas extraer diariamente las nuevas licitaciones relacionadas con "desarrollo de software" en España y estructurarlas en tu base de datos. Configurar las llamadas precisas a la API oficial, gestionar la paginación y, sobre todo, parsear los metadatos de los contratos requiere escribir bastante código repetitivo (boilerplate).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Una alternativa rápida para estructurar datos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para proyectos que necesitan iterar rápido y prefieren delegar la complejidad de la extracción y el parseo inicial, utilizar extractores específicos puede ser una gran ventaja. &lt;/p&gt;

&lt;p&gt;En lugar de construir el flujo desde cero contra la API oficial, puedes utilizar herramientas que ya entregan el dato limpio. Por ejemplo, puedes echar un vistazo a este &lt;a href="https://apify.com/devetty/eu-ted-tenders-scraper" rel="noopener noreferrer"&gt;EU TED Tenders Scraper&lt;/a&gt; disponible como actor en Apify. &lt;/p&gt;

&lt;p&gt;Este enfoque te permite configurar parámetros de búsqueda básicos (país, sector, fechas) y obtener directamente un JSON o CSV estructurado con la información clave de cada licitación (presupuesto, adjudicador, plazos, enlaces).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo conceptual de consumo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Si utilizas una solución automatizada como la mencionada, la integración en tu backend (por ejemplo, usando Node.js) se simplifica enormemente, pasando de gestionar endpoints complejos a simplemente consumir un webhook o un dataset estructurado:&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>apify</category>
      <category>data</category>
      <category>api</category>
    </item>
    <item>
      <title>Scraping 50k Spanish Public Tenders (PLACSP) into Clean JSON in &lt;26s with Apify</title>
      <dc:creator>Pablo Martinez</dc:creator>
      <pubDate>Sat, 31 Oct 2026 10:36:49 +0000</pubDate>
      <link>https://dev.to/pablotheblink/scraping-50k-spanish-public-tenders-placsp-into-clean-json-in-26s-with-apify-3el0</link>
      <guid>https://dev.to/pablotheblink/scraping-50k-spanish-public-tenders-placsp-into-clean-json-in-26s-with-apify-3el0</guid>
      <description>&lt;h1&gt;
  
  
  Scraping 50k Spanish Public Tenders (PLACSP) into Clean JSON in &amp;lt;26s with Apify
&lt;/h1&gt;

&lt;p&gt;Public procurement in Spain represents over &lt;strong&gt;€100 billion annually&lt;/strong&gt;. The Spanish central government, 17 autonomous regions, and thousands of municipal councils publish every tender, contract award, and minor RFP on the official procurement platform: &lt;strong&gt;PLACSP (&lt;em&gt;Plataforma de Contratación del Sector Público&lt;/em&gt;)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Under Spanish Law 37/2007 (Reutilización de la Información del Sector Público / RISP), this data is legally public and open. However, if you have ever tried to consume PLACSP data programmatically, you already know the engineering horror behind the curtain.&lt;/p&gt;

&lt;p&gt;In this technical showcase, we break down why traditional web scraping fails against PLACSP, how we engineered an Apify Actor that bypasses slow government XML feeds in sub-26 seconds using a dual-tier cache strategy, and how you can query active tenders in Python or cURL for $0.02 per result.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Engineering Problem: Why Scraping PLACSP is a Nightmare
&lt;/h2&gt;

&lt;p&gt;PLACSP provides an open syndication feed (&lt;code&gt;licitacionesPerfilesContratanteCompleto3.atom&lt;/code&gt;). On paper, it sounds simple: download Atom feeds, parse entries, load to your database. In production, five major bottlenecks break standard pipelines:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Legacy CODICE XML &amp;amp; Deep Namespaces
&lt;/h3&gt;

&lt;p&gt;PLACSP feeds do not return simple REST payloads. Each entry is wrapped in complex European CODICE XML standards:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;entry&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2005/Atom"&lt;/span&gt;
       &lt;span class="na"&gt;xmlns:cbc=&lt;/span&gt;&lt;span class="s"&gt;"urn:dgpe:names:draft:codice:schema:xsd:CommonBasicComponents-2"&lt;/span&gt;
       &lt;span class="na"&gt;xmlns:cac=&lt;/span&gt;&lt;span class="s"&gt;"urn:dgpe:names:draft:codice:schema:xsd:CommonAggregateComponents-2"&lt;/span&gt;
       &lt;span class="na"&gt;xmlns:cbc-place-ext=&lt;/span&gt;&lt;span class="s"&gt;"urn:dgpe:names:draft:codice-place-ext:schema:xsd:CommonBasicComponents-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;cac-place-ext:ContractFolderStatus&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;cbc:ContractFolderID&amp;gt;&lt;/span&gt;2026/00142&lt;span class="nt"&gt;&amp;lt;/cbc:ContractFolderID&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;cbc-place-ext:ContractFolderStatusCode&amp;gt;&lt;/span&gt;PUB&lt;span class="nt"&gt;&amp;lt;/cbc-place-ext:ContractFolderStatusCode&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;cac:ProcurementProject&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;cbc:Name&amp;gt;&lt;/span&gt;Mantenimiento de infraestructura cloud&lt;span class="nt"&gt;&amp;lt;/cbc:Name&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;cac:RequiredCommodityClassification&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;cbc:ItemClassificationCode&lt;/span&gt; &lt;span class="na"&gt;listURI=&lt;/span&gt;&lt;span class="s"&gt;"http://simap.europa.eu/cpv"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;72200000&lt;span class="nt"&gt;&amp;lt;/cbc:ItemClassificationCode&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/cac:RequiredCommodityClassification&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/cac:ProcurementProject&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/cac-place-ext:ContractFolderStatus&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/entry&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parsing these deep, polymorphic trees requires strict namespace management, fallback logic across multiple schema versions (&lt;code&gt;cbc&lt;/code&gt; vs &lt;code&gt;cbc-place-ext&lt;/code&gt;), and safe extraction of split date/time fields.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. High Latency &amp;amp; HTTP 504 Timeouts
&lt;/h3&gt;

&lt;p&gt;The official servers at &lt;code&gt;contrataciondelestado.es&lt;/code&gt; are notoriously fragile under load. A single paginated Atom document containing 500 records often takes &lt;strong&gt;15 to 30 seconds&lt;/strong&gt; to transfer. Traversing 10 to 15 pages in real-time will trigger scraper timeouts or gateway errors (&lt;code&gt;504 Gateway Timeout&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  3. State Tracking and Elapsed Deadlines
&lt;/h3&gt;

&lt;p&gt;More than 70% of entries in raw feeds are status changes (&lt;code&gt;EV&lt;/code&gt; for Evaluation, &lt;code&gt;RES&lt;/code&gt; for Awarded, &lt;code&gt;ADJ&lt;/code&gt; for Adjudicated) or tenders whose bid deadline elapsed weeks ago. To get &lt;em&gt;actionable&lt;/em&gt; leads, you must:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Filter exclusively for active status (&lt;code&gt;ContractFolderStatusCode: PUB&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Parse and validate submission deadlines against UTC &lt;code&gt;now()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Filter out tenders that close before your team can act.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. GDPR &amp;amp; Data Sanitization (Spanish Organic Law 3/2018)
&lt;/h3&gt;

&lt;p&gt;Public procurement tenders include names and personal tax IDs (DNI/NIE) of individual natural persons (sole traders and physical person representatives) inside contact tags. Publishing or processing these without explicit consent violates GDPR. A production-grade extractor must apply automated regex filters to suppress personal identifiers while preserving corporate tax IDs (CIF) and public contracting body names.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture: How the Apify Actor Achieves Sub-26s Runs
&lt;/h2&gt;

&lt;p&gt;To solve the speed and timeout constraints, the &lt;strong&gt;&lt;a href="https://apify.com/devetty/placsp-spain-tenders-scraper?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=placsp_showcase" rel="noopener noreferrer"&gt;PLACSP Spain Public Tenders Scraper&lt;/a&gt;&lt;/strong&gt; implements a &lt;strong&gt;dual-tier caching architecture&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ User Request / API Call ]
         │
         ▼
[ Apify Actor: placsp-spain-tenders-scraper ]
         │
         ├──► 1. Fetch Fast Hourly Cache (&amp;lt; 1.5s)
         │       (50k+ normalized active dossiers from CDN / tack.devetty.es)
         │
         ├──► 2. Live Feed Head Check (&amp;lt; 15s)
         │       (Pulls page 1 of PLACSP Atom feed to capture tenders published in the last 60 min)
         │
         ├──► 3. In-Memory Filter Engine (&amp;lt; 0.2s)
         │       - CPV Division match (e.g., '72' IT, '45' Construction, '50' Maintenance)
         │       - NUTS code &amp;amp; Territorial matcher (e.g., 'ES30' Madrid, 'ES51' Cataluña)
         │       - Budget ceiling without VAT (e.g., &amp;lt; 60.000 € for minor/simplified contracts)
         │       - Deadline validation (status == 'PUB' &amp;amp;&amp;amp; deadline &amp;gt; now())
         │       - GDPR sanitizer (strips DNI/NIE)
         │
         ▼
[ Output: Clean JSON Dataset &amp;amp; Apify Key-Value Store ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why this works:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Zero compute waste:&lt;/strong&gt; Instead of crawling 15 legacy XML pages from government servers on every run, the Actor loads an hourly pre-crawled and normalized dataset in compressed gzip format.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time accuracy:&lt;/strong&gt; It queries only the head of the live Atom stream (page 1) to ingest contracts published minutes ago.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execution time:&lt;/strong&gt; Complete extraction and filtering finishes in &lt;strong&gt;under 26 seconds&lt;/strong&gt;, well below Apify's default timeout limits.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Consuming the Actor: Code Examples
&lt;/h2&gt;

&lt;p&gt;The Actor is deployed as a &lt;strong&gt;Pay-Per-Event (PPE)&lt;/strong&gt; actor on the Apify Store at &lt;strong&gt;$0.02 per matching tender&lt;/strong&gt;. You only pay for exact tenders matching your criteria—never for compute time, pagination skips, or empty results.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Quick cURL Execution
&lt;/h3&gt;

&lt;p&gt;You can trigger a synchronous run and get JSON results directly via the Apify API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/devetty~placsp-spain-tenders-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "cpv_prefix": "72",
    "province_or_nuts": "Madrid",
    "nuts_prefix": "ES30",
    "max_budget": 100000,
    "status_filter": "PUB",
    "only_future_deadlines": true,
    "max_results": 20
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Production Python Integration (Apify Client)
&lt;/h3&gt;

&lt;p&gt;Here is a full Python script to stream active IT and software contracts (&lt;code&gt;CPV: 72&lt;/code&gt;) under €60,000 in Madrid and notify your CRM or messaging webhook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize the Apify client with your API token
&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# Define search parameters for Spanish public contracts
&lt;/span&gt;&lt;span class="n"&gt;run_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;# CPV 72: IT services: consulting, software development, Internet and support
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cpv_prefix&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;72&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;# Target region: Madrid (NUTS ES30)
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;province_or_nuts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Madrid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nuts_prefix&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ES30&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;# SME focus: Contracts under €60,000 (Simplified open procedure / Art. 159.6 LCSP)
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_budget&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;# Only open tenders currently accepting bids
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status_filter&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PUB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;only_future_deadlines&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_results&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[*] Running PLACSP scraper on Apify...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;devetty/placsp-spain-tenders-scraper&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Fetch results from the run's default dataset
&lt;/span&gt;&lt;span class="n"&gt;dataset_items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;list_items&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[*] Retrieved &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset_items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; active tenders matching criteria:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tender&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dataset_items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;📄 Dossier ID:   &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tender&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;expediente_id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;🏢 Authority:    &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tender&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;organo_contratacion&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;📌 Title:        &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tender&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;titulo&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;💰 Net Budget:   &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tender&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;presupuesto_sin_iva&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;,.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; € (Total: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tender&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;importe_total_con_iva&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;,.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; €)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;⏰ Bid Deadline: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tender&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;fecha_limite&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;🔗 Direct Link:  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tender&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;enlace_oficial&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;⚖️ Attribution:  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tender&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cita_legal&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Clean JSON Output Schema
&lt;/h2&gt;

&lt;p&gt;Every tender returned by the Actor conforms to a predictable schema ready for ingestion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expediente_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026/AR21U/00001560E"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"organo_contratacion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Subdirección General de Gestión Económica y Asuntos Generales"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"titulo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mantenimiento y conservación de redes de comunicaciones y servidores"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"presupuesto_sin_iva"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;33057.85&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"importe_total_con_iva"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;40000.00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fecha_limite"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-11-18 14:00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"estado"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PUB"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"enlace_oficial"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://contrataciondelestado.es/wps/poc?uri=deeplink:detalle_licitacion&amp;amp;idEvl=w1K9..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cpvs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"72500000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"72220000"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"provincias"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Madrid"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nuts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"ES300"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ciudades"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Madrid"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"codigos_postales"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"28071"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cita_legal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Origen de los datos: Plataforma de Contratación del Sector Público, Ministerio de Hacienda"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Fields:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;presupuesto_sin_iva&lt;/code&gt; &amp;amp; &lt;code&gt;importe_total_con_iva&lt;/code&gt;:&lt;/strong&gt; Clean floating-point values for budget threshold alerts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;enlace_oficial&lt;/code&gt;:&lt;/strong&gt; Verified deep-link resolving straight to the bidding dossier on &lt;code&gt;contrataciondelestado.es&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;cita_legal&lt;/code&gt;:&lt;/strong&gt; Mandatory attribution notice required by Spanish Law 37/2007 (RISP) pre-populated on every record for compliance.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Common Use Cases
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;GovTech SaaS &amp;amp; Alert Bots:&lt;/strong&gt; Build daily Slack/Telegram alerts for B2B contractors without operating your own XML infrastructure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SME &amp;amp; Freelance Bidding (Art. 159.6 LCSP):&lt;/strong&gt; Monitor simplified procedures (&lt;em&gt;Procedimiento Abierto Supersimplificado&lt;/em&gt;) under €60k where public bodies do not require provisional guarantees or heavy financial auditing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Market Intelligence &amp;amp; Price Benchmarking:&lt;/strong&gt; Track public procurement pricing trends and monitor competitor bids across specific CPV codes and autonomous regions.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;p&gt;The scraper is live and maintained on the Apify Store:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://apify.com/devetty/placsp-spain-tenders-scraper?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=placsp_showcase" rel="noopener noreferrer"&gt;Try the PLACSP Spain Public Tenders Scraper on Apify Store&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pricing: $0.02 / result event (Pay-Per-Event). Zero infrastructure overhead.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Appendix: Ready-to-Publish Community Posts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. LinkedIn B2B Engineering Post
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🚀 How we automated 50k Spanish Public Procurement Tenders (PLACSP) into clean JSON in &amp;lt;26s.

Public procurement in Spain exceeds €100B/year, but scraping the official Plataforma de Contratación del Sector Público (PLACSP) is notoriously painful:
- Legacy CODICE XML schemas with 5+ nested namespaces
- Slow Atom servers with frequent 504 timeouts (15-30s per page)
- 70% outdated or closed tenders
- Strict GDPR restrictions on personal DNIs

We built and published the official PLACSP scraper on Apify Store using a dual-tier cache architecture:
1. Hourly pre-crawled normalized cache (&amp;lt;1.5s response)
2. Live feed head check for tenders published in the last 60 minutes
3. Instant CPV (e.g. 72 IT, 50 Maintenance), NUTS territory, and budget filters (&amp;lt;60k€ for SMEs)
4. Full GDPR and Law 37/2007 Open Data compliance

Now available as a Pay-Per-Event Actor ($0.02/result) with direct JSON/CSV export and API integration:
https://apify.com/devetty/placsp-spain-tenders-scraper?utm_source=linkedin&amp;amp;utm_medium=post&amp;amp;utm_campaign=placsp_showcase

Full technical breakdown and Python integration code on Dev.to.

#GovTech #OpenData #WebScraping #Python #Apify #B2B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Twitter / X Thread
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1/4 Scraping Spanish Public Tenders (PLACSP) is an engineering nightmare: massive CODICE XML feeds, 504 server timeouts, and nested namespaces. 🇪🇸💻

Here is how we solved it to extract 50k+ active contracts in &amp;lt;26s with Python &amp;amp; @apify 👇

2/4 The bottleneck: PLACSP's syndication Atom feed serves 500 records/page, taking 20s+ per page. 
Our solution: Dual-tier caching. An hourly pre-crawled normalized cache + a 1-page live diff for the last 60 mins. Response time drops from 5 minutes to 24 seconds.

3/4 Filter directly by CPV (72 IT, 45 Construction, 50 Maintenance), budget (&amp;lt;60k€ for simplified SME contracts), and territorial NUTS (ES30 Madrid, ES51 BCN) with 100% GDPR sanitization.

4/4 Try the Actor on Apify Store (Pay-Per-Event, $0.02/tender):
https://apify.com/devetty/placsp-spain-tenders-scraper?utm_source=twitter&amp;amp;utm_medium=post&amp;amp;utm_campaign=placsp_showcase

Code examples &amp;amp; schema in our Dev.to showcase! #webscraping #opendata #python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Tech Forum / Indie Hackers Post
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Title: Building a sub-26s GovTech Scraper for Spanish Public Tenders ($0.02 Pay-Per-Event)

Hey hackers,

If you've ever explored European GovTech, you know public procurement is huge, but government APIs are stuck in 2008.

In Spain, all public contracts are published on PLACSP via Atom syndication feeds using CODICE XML schemas. We wanted to build automated alerts for SMEs targeting simplified contracts (&amp;lt;60k€ under Art. 159.6 LCSP), but hitting government servers live was causing constant timeouts.

We deployed an Apify Actor with a dual-cache model:
- Daily/hourly bulk crawl cached as normalized JSON.gz
- Live diff against page 1 of the Atom feed during actor startup
- Built-in filters for CPV categories, NUTS regions, and active bid deadlines
- Pay-Per-Event pricing on Apify Store ($0.02 per matching dossier)

Check out the actor here:
https://apify.com/devetty/placsp-spain-tenders-scraper?utm_source=indiehackers&amp;amp;utm_medium=community&amp;amp;utm_campaign=placsp_showcase

Would love feedback on our dual-cache approach from anyone else scraping heavy public data feeds!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>webscraping</category>
      <category>opendata</category>
      <category>python</category>
      <category>api</category>
    </item>
    <item>
      <title>How to Price UGC Deliverables: The Formula for Usage Rights, Whitelisting, and Exclusivity</title>
      <dc:creator>Pablo Martinez</dc:creator>
      <pubDate>Sat, 31 Oct 2026 10:36:14 +0000</pubDate>
      <link>https://dev.to/pablotheblink/how-to-price-ugc-deliverables-the-formula-for-usage-rights-whitelisting-and-exclusivity-1fee</link>
      <guid>https://dev.to/pablotheblink/how-to-price-ugc-deliverables-the-formula-for-usage-rights-whitelisting-and-exclusivity-1fee</guid>
      <description>&lt;p&gt;When software engineers transition into freelancing or building developer tooling, one of the earliest lessons is that you never bill intellectual property the same way you bill hourly maintenance. &lt;/p&gt;

&lt;p&gt;In the creator economy—specifically User-Generated Content (UGC) and short-form product marketing—an astonishing number of creators make the exact opposite mistake. They quote a flat fee for producing a video (say, $150 or €150) without separating &lt;strong&gt;production labor&lt;/strong&gt; from &lt;strong&gt;commercial distribution rights&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Two weeks later, they discover the client put $40,000 in Meta or TikTok ad spend behind their clip, running it as a dark ad across four countries while locking them out of pitching competitors in the same niche.&lt;/p&gt;

&lt;p&gt;If you don't unbundle your deliverables, you are essentially gifting brands free media distribution rights. Here is the operational pricing framework and mathematical formula used by professional creators and production studios to price UGC deals fairly, protect cash flow, and avoid leaving revenue on the table.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Core Components of a Commercial Creator Deal
&lt;/h2&gt;

&lt;p&gt;A professional UGC quote consists of three distinct layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Base Production Rate (Asset Creation):&lt;/strong&gt; This covers concept ideation, scripting, product handling, staging/lighting, filming, editing, color-grading, and standard captioning. This reflects pure creative labor and deliverable ownership for organic posting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paid Ad Usage Rights (Commercial Distribution):&lt;/strong&gt; Organic reach is free; paid ads generate revenue. When a brand runs your asset as a Spark Ad, Dark Post, or TikTok ad campaign, they extract compounding leverage from your likeness and creative angle. Ad usage is traditionally priced as a monthly percentage of your base production rate (industry standard: 30% to 50% per 30-day window).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exclusivity &amp;amp; Category Lockout:&lt;/strong&gt; If a fintech app requires that you do not partner with or create content for competing financial products for 60 days, you are incurring a direct opportunity cost. Exclusivity must always carry a premium—typically 30% to 100% of the base fee per month depending on how narrow the niche is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Creative Variations (Hook Testing):&lt;/strong&gt; Performance marketing teams rarely run a single video in isolation. They need multiple hook variations (the first 3 seconds) and call-to-action (CTA) variations to test ad retention. Hooks require marginal filming time but offer massive testing utility. They should be priced at 20% to 25% of the base video rate.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  2. The Pricing Formula
&lt;/h2&gt;

&lt;p&gt;To keep your quoting deterministic, transparent, and defensible in client negotiations, use this formula:&lt;/p&gt;

&lt;p&gt;$$\text{Total Quote} = (\text{Base Rate} \times V) + (H \times 0.25 \times \text{Base Rate}) + (M \times U \times \text{Base Deliverables}) + E$$&lt;/p&gt;

&lt;p&gt;Where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$V$ = Number of finished video deliverables&lt;/li&gt;
&lt;li&gt;$H$ = Number of additional hook / CTA variations&lt;/li&gt;
&lt;li&gt;$M$ = Months of paid ad usage rights&lt;/li&gt;
&lt;li&gt;$U$ = Ad usage percentage per month (default: 30%)&lt;/li&gt;
&lt;li&gt;$E$ = Exclusivity premium (0 if non-exclusive)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. A Step-by-Step Example with Real Numbers
&lt;/h2&gt;

&lt;p&gt;Let’s walk through a common agency brief:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deliverable:&lt;/strong&gt; 2 organic vertical videos (9:16) for a SaaS product&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variations:&lt;/strong&gt; 2 additional hook variations for split testing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usage:&lt;/strong&gt; 30 days (1 month) of paid ad / whitelisting rights&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exclusivity:&lt;/strong&gt; 30 days of category exclusivity in direct software competitors&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Math:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Base Production:&lt;/strong&gt;&lt;br&gt;
$$2 \text{ videos} \times €150 = €300$$&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hook Variations:&lt;/strong&gt;&lt;br&gt;
$$2 \text{ extra hooks} \times (25\% \text{ of } €150) = 2 \times €37.50 = €75$$&lt;br&gt;
&lt;em&gt;Subtotal Assets:&lt;/em&gt; €375&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Paid Ad Usage (30 days):&lt;/strong&gt;&lt;br&gt;
$$1 \text{ month} \times (30\% \text{ of } €300 \text{ base deliverables}) = €90$$&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Category Exclusivity (30 days):&lt;/strong&gt;&lt;br&gt;
$$30\% \text{ exclusivity premium on base deliverables} = €90$$&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Final Commercial Quote:&lt;/strong&gt;&lt;br&gt;
$$€300 + €75 + €90 + €90 = €555$$&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If this creator had quoted a naive flat rate of €150 per video, they would have delivered €555 worth of commercial utility for €300. By structuring the quote line by line, the client understands exactly what they are paying for: base creative labor, testing assets, media rights, and market protection.&lt;/p&gt;

&lt;p&gt;If you want to simulate variations or test different duration windows without doing manual spreadsheets, you can test the open &lt;a href="https://ugc-deal-tracker.devetty.es?utm_source=devto" rel="noopener noreferrer"&gt;UGC Rate &amp;amp; Usage Rights Calculator&lt;/a&gt; to calculate quotes and upfront deposits in seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Payment Terms: Protecting Cash Flow
&lt;/h2&gt;

&lt;p&gt;Closing the deal is only half the battle. In B2B marketing, Net-30 or Net-60 invoice terms often mean waiting two months for payout, while clients occasionally default on usage expiration dates.&lt;/p&gt;

&lt;p&gt;To protect your business:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;50% Upfront Deposit:&lt;/strong&gt; Never film or ship finals without an initial 50% deposit cleared in your bank account. In our example above, invoice €277.50 before touching a camera.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watermarked Drafts:&lt;/strong&gt; Deliver review cuts with a clear, semi-transparent timecode watermark. Release raw or clean files only upon balance settlement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usage Expiration Tracking:&lt;/strong&gt; Include strict start and end dates for paid ad rights directly in the contract. Once day 31 hits, the brand must either pull the ad from Ads Manager or renew usage for another monthly fee.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Treating creator production as an engineering workflow—with clean formulas, structured deliverables, and strict licensing terms—turns irregular creative gigs into predictable, profitable client relationships.&lt;/p&gt;

</description>
      <category>freelance</category>
      <category>creators</category>
      <category>pricing</category>
      <category>career</category>
    </item>
  </channel>
</rss>
